|
|
@ -40,24 +40,43 @@ char *createFilename(char *buffer, const dir_t &p) { //buffer > 12characters |
|
|
|
return buffer; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* Dive into a folder and recurse depth-first to perform a pre-set operation lsAction: |
|
|
|
* LS_Count - Add +1 to nrFiles for every file within the parent |
|
|
|
* LS_GetFilename - Get the filename of the file indexed by nrFiles |
|
|
|
* LS_SerialPrint - Print the full path of each file to serial output |
|
|
|
*/ |
|
|
|
void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/) { |
|
|
|
dir_t p; |
|
|
|
uint8_t cnt = 0; |
|
|
|
|
|
|
|
// Read the next entry from a directory
|
|
|
|
while (parent.readDir(p, longFilename) > 0) { |
|
|
|
if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { // hence LS_SerialPrint
|
|
|
|
char path[FILENAME_LENGTH*2]; |
|
|
|
|
|
|
|
// If the entry is a directory and the action is LS_SerialPrint
|
|
|
|
if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { |
|
|
|
|
|
|
|
// Allocate enough stack space for the full path to a folder
|
|
|
|
int len = strlen(prepend) + FILENAME_LENGTH + 1; |
|
|
|
char path[len]; |
|
|
|
|
|
|
|
// Get the short name for the item, which we know is a folder
|
|
|
|
char lfilename[FILENAME_LENGTH]; |
|
|
|
createFilename(lfilename, p); |
|
|
|
|
|
|
|
path[0] = 0; |
|
|
|
if (prepend[0] == 0) strcat(path, "/"); //avoid leading / if already in prepend
|
|
|
|
// Append the FOLDERNAME12/ to the passed string.
|
|
|
|
// It contains the full path to the "parent" argument.
|
|
|
|
// We now have the full path to the item in this folder.
|
|
|
|
path[0] = '\0'; |
|
|
|
if (prepend[0] == '\0') strcat(path, "/"); // a root slash if prepend is empty
|
|
|
|
strcat(path, prepend); |
|
|
|
strcat(path, lfilename); |
|
|
|
strcat(path, "/"); |
|
|
|
|
|
|
|
//Serial.print(path);
|
|
|
|
// Serial.print(path);
|
|
|
|
|
|
|
|
// Get a new directory object using the full path
|
|
|
|
// and dive recursively into it.
|
|
|
|
SdFile dir; |
|
|
|
if (!dir.open(parent, lfilename, O_READ)) { |
|
|
|
if (lsAction == LS_SerialPrint) { |
|
|
@ -67,14 +86,13 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m |
|
|
|
} |
|
|
|
} |
|
|
|
lsDive(path, dir); |
|
|
|
//close done automatically by destructor of SdFile
|
|
|
|
// close() is done automatically by destructor of SdFile
|
|
|
|
} |
|
|
|
else { |
|
|
|
char pn0 = p.name[0]; |
|
|
|
if (pn0 == DIR_NAME_FREE) break; |
|
|
|
if (pn0 == DIR_NAME_DELETED || pn0 == '.') continue; |
|
|
|
char lf0 = longFilename[0]; |
|
|
|
if (lf0 == '.') continue; |
|
|
|
if (longFilename[0] == '.') continue; |
|
|
|
|
|
|
|
if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue; |
|
|
|
|
|
|
@ -82,24 +100,27 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m |
|
|
|
|
|
|
|
if (!filenameIsDir && (p.name[8] != 'G' || p.name[9] == '~')) continue; |
|
|
|
|
|
|
|
//if (cnt++ != nr) continue;
|
|
|
|
createFilename(filename, p); |
|
|
|
if (lsAction == LS_SerialPrint) { |
|
|
|
SERIAL_PROTOCOL(prepend); |
|
|
|
SERIAL_PROTOCOLLN(filename); |
|
|
|
} |
|
|
|
else if (lsAction == LS_Count) { |
|
|
|
nrFiles++; |
|
|
|
} |
|
|
|
else if (lsAction == LS_GetFilename) { |
|
|
|
if (match != NULL) { |
|
|
|
if (strcasecmp(match, filename) == 0) return; |
|
|
|
} |
|
|
|
else if (cnt == nrFiles) return; |
|
|
|
cnt++; |
|
|
|
switch (lsAction) { |
|
|
|
case LS_Count: |
|
|
|
nrFiles++; |
|
|
|
break; |
|
|
|
case LS_SerialPrint: |
|
|
|
createFilename(filename, p); |
|
|
|
SERIAL_PROTOCOL(prepend); |
|
|
|
SERIAL_PROTOCOLLN(filename); |
|
|
|
break; |
|
|
|
case LS_GetFilename: |
|
|
|
createFilename(filename, p); |
|
|
|
if (match != NULL) { |
|
|
|
if (strcasecmp(match, filename) == 0) return; |
|
|
|
} |
|
|
|
else if (cnt == nrFiles) return; |
|
|
|
cnt++; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} // while readDir
|
|
|
|
} |
|
|
|
|
|
|
|
void CardReader::ls() { |
|
|
@ -238,7 +259,7 @@ void CardReader::openFile(char* name, bool read, bool replace_current/*=true*/) |
|
|
|
char *dirname_start, *dirname_end; |
|
|
|
if (name[0] == '/') { |
|
|
|
dirname_start = &name[1]; |
|
|
|
while(dirname_start > 0) { |
|
|
|
while (dirname_start > 0) { |
|
|
|
dirname_end = strchr(dirname_start, '/'); |
|
|
|
//SERIAL_ECHO("start:");SERIAL_ECHOLN((int)(dirname_start - name));
|
|
|
|
//SERIAL_ECHO("end :");SERIAL_ECHOLN((int)(dirname_end - name));
|
|
|
@ -288,14 +309,14 @@ void CardReader::openFile(char* name, bool read, bool replace_current/*=true*/) |
|
|
|
else { |
|
|
|
SERIAL_PROTOCOLPGM(MSG_SD_OPEN_FILE_FAIL); |
|
|
|
SERIAL_PROTOCOL(fname); |
|
|
|
SERIAL_PROTOCOLCHAR('.'); |
|
|
|
SERIAL_PROTOCOLPGM(".\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
else { //write
|
|
|
|
if (!file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) { |
|
|
|
SERIAL_PROTOCOLPGM(MSG_SD_OPEN_FILE_FAIL); |
|
|
|
SERIAL_PROTOCOL(fname); |
|
|
|
SERIAL_PROTOCOLCHAR('.'); |
|
|
|
SERIAL_PROTOCOLPGM(".\n"); |
|
|
|
} |
|
|
|
else { |
|
|
|
saving = true; |
|
|
|