|
@ -11,8 +11,7 @@ |
|
|
|
|
|
|
|
|
CardReader::CardReader() |
|
|
CardReader::CardReader() |
|
|
{ |
|
|
{ |
|
|
#if defined(SDCARD_SORT_ALPHA) && SORT_USES_MORE_RAM |
|
|
#ifdef SDCARD_SORT_ALPHA |
|
|
sortnames = NULL; |
|
|
|
|
|
sort_count = 0; |
|
|
sort_count = 0; |
|
|
#endif |
|
|
#endif |
|
|
filesize = 0; |
|
|
filesize = 0; |
|
@ -40,13 +39,9 @@ CardReader::CardReader() |
|
|
char *createFilename(char *buffer, const dir_t &p) //buffer>12characters
|
|
|
char *createFilename(char *buffer, const dir_t &p) //buffer>12characters
|
|
|
{ |
|
|
{ |
|
|
char *pos=buffer; |
|
|
char *pos=buffer; |
|
|
for (uint8_t i = 0; i < 11; i++) |
|
|
for (uint8_t i = 0; i < 11; i++) { |
|
|
{ |
|
|
|
|
|
if (p.name[i] == ' ') continue; |
|
|
if (p.name[i] == ' ') continue; |
|
|
if (i == 8) |
|
|
if (i == 8) *pos++ = '.'; |
|
|
{ |
|
|
|
|
|
*pos++='.'; |
|
|
|
|
|
} |
|
|
|
|
|
*pos++ = p.name[i]; |
|
|
*pos++ = p.name[i]; |
|
|
} |
|
|
} |
|
|
*pos++ = 0; |
|
|
*pos++ = 0; |
|
@ -59,7 +54,7 @@ void CardReader::lsDive(const char *prepend,SdFile parent) |
|
|
dir_t p; |
|
|
dir_t p; |
|
|
uint8_t cnt=0; |
|
|
uint8_t cnt=0; |
|
|
|
|
|
|
|
|
while (parent.readDir(p, diveFilename) > 0) |
|
|
while (parent.readDir(p, longFilename) > 0) |
|
|
{ |
|
|
{ |
|
|
if( DIR_IS_SUBDIR(&p) && lsAction!=LS_Count && lsAction!=LS_GetFilename) // hence LS_SerialPrint
|
|
|
if( DIR_IS_SUBDIR(&p) && lsAction!=LS_Count && lsAction!=LS_GetFilename) // hence LS_SerialPrint
|
|
|
{ |
|
|
{ |
|
@ -96,8 +91,8 @@ void CardReader::lsDive(const char *prepend,SdFile parent) |
|
|
{ |
|
|
{ |
|
|
if (p.name[0] == DIR_NAME_FREE) break; |
|
|
if (p.name[0] == DIR_NAME_FREE) break; |
|
|
if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.'|| p.name[0] == '_') continue; |
|
|
if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.'|| p.name[0] == '_') continue; |
|
|
if (diveFilename[0] != '\0' && |
|
|
if (longFilename[0] != '\0' && |
|
|
(diveFilename[0] == '.' || diveFilename[0] == '_')) continue; |
|
|
(longFilename[0] == '.' || longFilename[0] == '_')) continue; |
|
|
if ( p.name[0] == '.') |
|
|
if ( p.name[0] == '.') |
|
|
{ |
|
|
{ |
|
|
if ( p.name[1] != '.') |
|
|
if ( p.name[1] != '.') |
|
@ -556,21 +551,20 @@ void CardReader::closefile(bool store_location) |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void CardReader::getfilename(const uint8_t nr) |
|
|
void CardReader::getfilename(const uint16_t nr) |
|
|
{ |
|
|
{ |
|
|
#if defined(SDCARD_SORT_ALPHA) && SORT_USES_MORE_RAM |
|
|
#if defined(SDCARD_SORT_ALPHA) && SORT_USES_RAM && SORT_USES_MORE_RAM |
|
|
if (nr < sort_count) { |
|
|
if (nr < sort_count) { |
|
|
strcpy(diveFilename, sortnames[nr]); |
|
|
strcpy(longFilename, sortnames[nr]); |
|
|
|
|
|
filenameIsDir = isDir[nr]; |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
curDir=&workDir; |
|
|
curDir=&workDir; |
|
|
lsAction=LS_GetFilename; |
|
|
lsAction=LS_GetFilename; |
|
|
nrFiles=nr; |
|
|
nrFiles=nr; |
|
|
curDir->rewind(); |
|
|
curDir->rewind(); |
|
|
lsDive("",*curDir); |
|
|
lsDive("",*curDir); |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
uint16_t CardReader::getnrfilenames() |
|
|
uint16_t CardReader::getnrfilenames() |
|
@ -631,12 +625,8 @@ void CardReader::updir() |
|
|
/**
|
|
|
/**
|
|
|
* Get the name of a file in the current directory by sort-index |
|
|
* Get the name of a file in the current directory by sort-index |
|
|
*/ |
|
|
*/ |
|
|
void CardReader::getfilename_sorted(const uint8_t nr) { |
|
|
void CardReader::getfilename_sorted(const uint16_t nr) { |
|
|
#if SORT_USES_MORE_RAM |
|
|
|
|
|
getfilename(nr < sort_count ? sort_order[nr] : nr); |
|
|
getfilename(nr < sort_count ? sort_order[nr] : nr); |
|
|
#else |
|
|
|
|
|
getfilename(nr < SORT_LIMIT ? sort_order[nr] : nr); |
|
|
|
|
|
#endif |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/**
|
|
|
/**
|
|
@ -656,68 +646,73 @@ void CardReader::presort() |
|
|
|
|
|
|
|
|
if (fileCnt > SORT_LIMIT) fileCnt = SORT_LIMIT; |
|
|
if (fileCnt > SORT_LIMIT) fileCnt = SORT_LIMIT; |
|
|
|
|
|
|
|
|
|
|
|
#if SORT_USES_RAM |
|
|
#if SORT_USES_MORE_RAM |
|
|
#if SORT_USES_MORE_RAM |
|
|
sortnames = (char**)malloc(fileCnt * sizeof(char*)); |
|
|
sortnames = (char**)calloc(fileCnt, sizeof(char*)); |
|
|
sort_count = fileCnt; |
|
|
#else |
|
|
#elif SORT_USES_RAM |
|
|
|
|
|
char *sortnames[fileCnt]; |
|
|
char *sortnames[fileCnt]; |
|
|
#if FOLDER_SORTING != 0 |
|
|
|
|
|
uint8_t isdir[fileCnt]; |
|
|
|
|
|
#endif |
|
|
#endif |
|
|
#else |
|
|
#else |
|
|
char sortname[LONG_FILENAME_LENGTH+1]; |
|
|
char name1[LONG_FILENAME_LENGTH+1]; |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if FOLDER_SORTING != 0 |
|
|
|
|
|
#if SORT_USES_RAM && SORT_USES_MORE_RAM |
|
|
|
|
|
isDir = (uint8_t*)calloc(fileCnt, sizeof(uint8_t)); |
|
|
|
|
|
#else |
|
|
|
|
|
uint8_t isDir[fileCnt]; |
|
|
|
|
|
#endif |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
sort_count = fileCnt; |
|
|
|
|
|
sort_order = new uint8_t[fileCnt]; |
|
|
|
|
|
|
|
|
if (fileCnt > 1) { |
|
|
if (fileCnt > 1) { |
|
|
|
|
|
|
|
|
// Init sort order [and get filenames]
|
|
|
// Init sort order. If using RAM then read all filenames now.
|
|
|
for (int i=0; i<fileCnt; i++) { |
|
|
for (uint16_t i=0; i<fileCnt; i++) { |
|
|
int byte=i/8, bit=1<<(i%8); |
|
|
|
|
|
sort_order[i] = i; |
|
|
sort_order[i] = i; |
|
|
#if SORT_USES_RAM |
|
|
#if SORT_USES_RAM |
|
|
getfilename(i); |
|
|
getfilename(i); |
|
|
char *name = diveFilename[0] ? diveFilename : filename; |
|
|
sortnames[i] = strdup(longFilename[0] ? longFilename : filename); |
|
|
// SERIAL_ECHOPGM("--- ");
|
|
|
// char out[30];
|
|
|
// SERIAL_ECHOLN(name);
|
|
|
// sprintf_P(out, PSTR("---- %i %s %s"), i, filenameIsDir ? "D" : " ", sortnames[i]);
|
|
|
sortnames[i] = (char*)malloc(strlen(name) + 1); |
|
|
// SERIAL_ECHOLN(out);
|
|
|
strcpy(sortnames[i], name); |
|
|
|
|
|
#if FOLDER_SORTING != 0 |
|
|
#if FOLDER_SORTING != 0 |
|
|
isdir[i] = filenameIsDir; |
|
|
isDir[i] = filenameIsDir; |
|
|
#endif |
|
|
#endif |
|
|
#endif |
|
|
#endif |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Bubble Sort
|
|
|
// Bubble Sort
|
|
|
for (uint8_t i=fileCnt; --i;) { |
|
|
for (uint16_t i=fileCnt; --i;) { |
|
|
bool cmp, didSwap = false; |
|
|
bool cmp, didSwap = false; |
|
|
for (uint8_t j=0; j<i; ++j) { |
|
|
for (uint16_t j=0; j<i; ++j) { |
|
|
int s1 = j, s2 = j+1, o1 = sort_order[s1], o2 = sort_order[s2]; |
|
|
uint16_t s1 = j, s2 = j+1, o1 = sort_order[s1], o2 = sort_order[s2]; |
|
|
#if SORT_USES_RAM |
|
|
#if SORT_USES_RAM |
|
|
#if FOLDER_SORTING != 0 |
|
|
#if FOLDER_SORTING != 0 |
|
|
cmp = (isdir[o1] == isdir[o2]) ? (strcasecmp(sortnames[o1], sortnames[o2]) > 0) : isdir[FOLDER_SORTING > 0 ? o1 : o2]; |
|
|
cmp = (isDir[o1] == isDir[o2]) ? (strcasecmp(sortnames[o1], sortnames[o2]) > 0) : isDir[FOLDER_SORTING > 0 ? o1 : o2]; |
|
|
#else |
|
|
#else |
|
|
cmp = strcasecmp(sortnames[o1], sortnames[o2]) > 0); |
|
|
cmp = strcasecmp(sortnames[o1], sortnames[o2]) > 0; |
|
|
#endif |
|
|
#endif |
|
|
#else |
|
|
#else |
|
|
getfilename(o1); |
|
|
getfilename(o1); |
|
|
|
|
|
strcpy(name1, longFilename[0] ? longFilename : filename); |
|
|
#if FOLDER_SORTING != 0 |
|
|
#if FOLDER_SORTING != 0 |
|
|
bool dir1 = filenameIsDir; |
|
|
bool dir1 = filenameIsDir; |
|
|
#endif |
|
|
#endif |
|
|
char *name = diveFilename[0] ? diveFilename : filename; |
|
|
|
|
|
strcpy(sortname, name); |
|
|
|
|
|
getfilename(o2); |
|
|
getfilename(o2); |
|
|
name = diveFilename[0] ? diveFilename : filename; |
|
|
char *name2 = longFilename[0] ? longFilename : filename; |
|
|
#if FOLDER_SORTING != 0 |
|
|
#if FOLDER_SORTING != 0 |
|
|
cmp = (dir1 == filenameIsDir) ? (strcasecmp(sortname, name) > 0) : (FOLDER_SORTING > 0 ? dir1 : !dir1); |
|
|
cmp = (dir1 == filenameIsDir) ? (strcasecmp(name1, name2) > 0) : (FOLDER_SORTING > 0 ? dir1 : !dir1); |
|
|
#else |
|
|
#else |
|
|
cmp = strcasecmp(sortname, name) > 0); |
|
|
cmp = strcasecmp(name1, name2) > 0; |
|
|
#endif |
|
|
#endif |
|
|
#endif |
|
|
#endif |
|
|
if (cmp) { |
|
|
if (cmp) { |
|
|
// SERIAL_ECHOPGM("Swap ");
|
|
|
// char out[LONG_FILENAME_LENGTH*2+20];
|
|
|
// SERIAL_ECHOLN(sortnames[o1]);
|
|
|
// sprintf_P(out, PSTR("Swap %i %s for %i %s"), o1, sortnames[o1], o2, sortnames[o2]);
|
|
|
// SERIAL_ECHOPGM(" for ");
|
|
|
// SERIAL_ECHOLN(out);
|
|
|
// SERIAL_ECHOLN(sortnames[o2]);
|
|
|
|
|
|
sort_order[s1] = o2; |
|
|
sort_order[s1] = o2; |
|
|
sort_order[s2] = o1; |
|
|
sort_order[s2] = o1; |
|
|
didSwap = true; |
|
|
didSwap = true; |
|
@ -727,30 +722,32 @@ void CardReader::presort() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#if SORT_USES_RAM && !SORT_USES_MORE_RAM |
|
|
#if SORT_USES_RAM && !SORT_USES_MORE_RAM |
|
|
for (int i=0; i < fileCnt; ++i) free(sortnames[i]); |
|
|
for (uint16_t i=0; i<fileCnt; ++i) free(sortnames[i]); |
|
|
#endif |
|
|
#endif |
|
|
} |
|
|
} |
|
|
else { |
|
|
else { |
|
|
sort_order[0] = 0; |
|
|
sort_order[0] = 0; |
|
|
|
|
|
#if SORT_USES_RAM && SORT_USES_MORE_RAM |
|
|
|
|
|
sortnames = (char**)malloc(sizeof(char*)); |
|
|
|
|
|
isDir = (uint8_t*)malloc(sizeof(uint8_t)); |
|
|
|
|
|
getfilename(0); |
|
|
|
|
|
sortnames[0] = strdup(longFilename[0] ? longFilename : filename); |
|
|
|
|
|
isDir[0] = filenameIsDir; |
|
|
|
|
|
#endif |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void CardReader::flush_presort() { |
|
|
void CardReader::flush_presort() { |
|
|
#if SORT_USES_MORE_RAM |
|
|
|
|
|
if (sort_count > 0) { |
|
|
if (sort_count > 0) { |
|
|
for (int i=0; i < sort_count; ++i) { |
|
|
#if SORT_USES_RAM && SORT_USES_MORE_RAM |
|
|
free(sortnames[i]); |
|
|
for (uint8_t i=0; i<sort_count; ++i) free(sortnames[i]); |
|
|
sort_order[i] = i; |
|
|
|
|
|
} |
|
|
|
|
|
free(sortnames); |
|
|
free(sortnames); |
|
|
sortnames = NULL; |
|
|
#endif |
|
|
|
|
|
delete sort_order; |
|
|
sort_count = 0; |
|
|
sort_count = 0; |
|
|
} |
|
|
} |
|
|
#else |
|
|
|
|
|
for (int i=SORT_LIMIT; --i;) sort_order[i] = i; |
|
|
|
|
|
#endif |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#endif // SDCARD_SORT_ALPHA
|
|
|
#endif // SDCARD_SORT_ALPHA
|
|
|