|
@@ -11,6 +11,10 @@
|
11
|
11
|
|
12
|
12
|
CardReader::CardReader()
|
13
|
13
|
{
|
|
14
|
+ #if SORT_USES_MORE_RAM
|
|
15
|
+ sortnames = NULL;
|
|
16
|
+ sort_count = 0;
|
|
17
|
+ #endif
|
14
|
18
|
filesize = 0;
|
15
|
19
|
sdpos = 0;
|
16
|
20
|
sdprinting = false;
|
|
@@ -53,15 +57,15 @@ char *createFilename(char *buffer,const dir_t &p) //buffer>12characters
|
53
|
57
|
void CardReader::lsDive(const char *prepend,SdFile parent)
|
54
|
58
|
{
|
55
|
59
|
dir_t p;
|
56
|
|
- uint8_t cnt=0;
|
|
60
|
+ uint8_t cnt=0;
|
57
|
61
|
|
58
|
|
- while (parent.readDir(p, longFilename) > 0)
|
|
62
|
+ while (parent.readDir(p, diveFilename) > 0)
|
59
|
63
|
{
|
60
|
64
|
if( DIR_IS_SUBDIR(&p) && lsAction!=LS_Count && lsAction!=LS_GetFilename) // hence LS_SerialPrint
|
61
|
65
|
{
|
62
|
66
|
|
63
|
|
- char path[13*2];
|
64
|
|
- char lfilename[13];
|
|
67
|
+ char path[FILENAME_LENGTH*2];
|
|
68
|
+ char lfilename[FILENAME_LENGTH];
|
65
|
69
|
createFilename(lfilename,p);
|
66
|
70
|
|
67
|
71
|
path[0]=0;
|
|
@@ -87,25 +91,22 @@ void CardReader::lsDive(const char *prepend,SdFile parent)
|
87
|
91
|
}
|
88
|
92
|
lsDive(path,dir);
|
89
|
93
|
//close done automatically by destructor of SdFile
|
90
|
|
-
|
91
|
|
-
|
92
|
94
|
}
|
93
|
95
|
else
|
94
|
96
|
{
|
95
|
97
|
if (p.name[0] == DIR_NAME_FREE) break;
|
96
|
98
|
if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.'|| p.name[0] == '_') continue;
|
97
|
|
- if (longFilename[0] != '\0' &&
|
98
|
|
- (longFilename[0] == '.' || longFilename[0] == '_')) continue;
|
|
99
|
+ if (diveFilename[0] != '\0' &&
|
|
100
|
+ (diveFilename[0] == '.' || diveFilename[0] == '_')) continue;
|
99
|
101
|
if ( p.name[0] == '.')
|
100
|
102
|
{
|
101
|
103
|
if ( p.name[1] != '.')
|
102
|
104
|
continue;
|
103
|
105
|
}
|
104
|
|
-
|
|
106
|
+
|
105
|
107
|
if (!DIR_IS_FILE_OR_SUBDIR(&p)) continue;
|
106
|
108
|
filenameIsDir=DIR_IS_SUBDIR(&p);
|
107
|
|
-
|
108
|
|
-
|
|
109
|
+
|
109
|
110
|
if(!filenameIsDir)
|
110
|
111
|
{
|
111
|
112
|
if(p.name[8]!='G') continue;
|
|
@@ -124,10 +125,8 @@ void CardReader::lsDive(const char *prepend,SdFile parent)
|
124
|
125
|
}
|
125
|
126
|
else if(lsAction==LS_GetFilename)
|
126
|
127
|
{
|
127
|
|
- if(cnt==nrFiles)
|
128
|
|
- return;
|
|
128
|
+ if (cnt == nrFiles) return;
|
129
|
129
|
cnt++;
|
130
|
|
-
|
131
|
130
|
}
|
132
|
131
|
}
|
133
|
132
|
}
|
|
@@ -136,9 +135,6 @@ void CardReader::lsDive(const char *prepend,SdFile parent)
|
136
|
135
|
void CardReader::ls()
|
137
|
136
|
{
|
138
|
137
|
lsAction=LS_SerialPrint;
|
139
|
|
- if(lsAction==LS_Count)
|
140
|
|
- nrFiles=0;
|
141
|
|
-
|
142
|
138
|
root.rewind();
|
143
|
139
|
lsDive("",root);
|
144
|
140
|
}
|
|
@@ -177,6 +173,9 @@ void CardReader::initsd()
|
177
|
173
|
}
|
178
|
174
|
workDir=root;
|
179
|
175
|
curDir=&root;
|
|
176
|
+ #ifdef SDCARD_SORT_ALPHA
|
|
177
|
+ presort();
|
|
178
|
+ #endif
|
180
|
179
|
/*
|
181
|
180
|
if(!workDir.openRoot(&volume))
|
182
|
181
|
{
|
|
@@ -193,8 +192,10 @@ void CardReader::setroot()
|
193
|
192
|
SERIAL_ECHOLNPGM(MSG_SD_WORKDIR_FAIL);
|
194
|
193
|
}*/
|
195
|
194
|
workDir=root;
|
196
|
|
-
|
197
|
195
|
curDir=&workDir;
|
|
196
|
+ #ifdef SDCARD_SORT_ALPHA
|
|
197
|
+ presort();
|
|
198
|
+ #endif
|
198
|
199
|
}
|
199
|
200
|
void CardReader::release()
|
200
|
201
|
{
|
|
@@ -235,7 +236,7 @@ void CardReader::getAbsFilename(char *t)
|
235
|
236
|
while(*t!=0 && cnt< MAXPATHNAMELENGTH)
|
236
|
237
|
{t++;cnt++;} //crawl counter forward.
|
237
|
238
|
}
|
238
|
|
- if(cnt<MAXPATHNAMELENGTH-13)
|
|
239
|
+ if(cnt<MAXPATHNAMELENGTH-FILENAME_LENGTH)
|
239
|
240
|
file.getFilename(t);
|
240
|
241
|
else
|
241
|
242
|
t[0]=0;
|
|
@@ -305,7 +306,7 @@ void CardReader::openFile(char* name,bool read, bool replace_current/*=true*/)
|
305
|
306
|
//SERIAL_ECHO("end :");SERIAL_ECHOLN((int)(dirname_end-name));
|
306
|
307
|
if(dirname_end>0 && dirname_end>dirname_start)
|
307
|
308
|
{
|
308
|
|
- char subdirname[13];
|
|
309
|
+ char subdirname[FILENAME_LENGTH];
|
309
|
310
|
strncpy(subdirname, dirname_start, dirname_end-dirname_start);
|
310
|
311
|
subdirname[dirname_end-dirname_start]=0;
|
311
|
312
|
SERIAL_ECHOLN(subdirname);
|
|
@@ -401,7 +402,7 @@ void CardReader::removeFile(char* name)
|
401
|
402
|
//SERIAL_ECHO("end :");SERIAL_ECHOLN((int)(dirname_end-name));
|
402
|
403
|
if(dirname_end>0 && dirname_end>dirname_start)
|
403
|
404
|
{
|
404
|
|
- char subdirname[13];
|
|
405
|
+ char subdirname[FILENAME_LENGTH];
|
405
|
406
|
strncpy(subdirname, dirname_start, dirname_end-dirname_start);
|
406
|
407
|
subdirname[dirname_end-dirname_start]=0;
|
407
|
408
|
SERIAL_ECHOLN(subdirname);
|
|
@@ -439,6 +440,9 @@ void CardReader::removeFile(char* name)
|
439
|
440
|
SERIAL_PROTOCOLPGM("File deleted:");
|
440
|
441
|
SERIAL_PROTOCOLLN(fname);
|
441
|
442
|
sdpos = 0;
|
|
443
|
+ #ifdef SDCARD_SORT_ALPHA
|
|
444
|
+ presort();
|
|
445
|
+ #endif
|
442
|
446
|
}
|
443
|
447
|
else
|
444
|
448
|
{
|
|
@@ -577,7 +581,7 @@ void CardReader::chdir(const char * relpath)
|
577
|
581
|
{
|
578
|
582
|
SdFile newfile;
|
579
|
583
|
SdFile *parent=&root;
|
580
|
|
-
|
|
584
|
+
|
581
|
585
|
if(workDir.isOpen())
|
582
|
586
|
parent=&workDir;
|
583
|
587
|
|
|
@@ -595,21 +599,156 @@ void CardReader::chdir(const char * relpath)
|
595
|
599
|
workDirParents[0]=*parent;
|
596
|
600
|
}
|
597
|
601
|
workDir=newfile;
|
|
602
|
+ #ifdef SDCARD_SORT_ALPHA
|
|
603
|
+ presort();
|
|
604
|
+ #endif
|
598
|
605
|
}
|
599
|
606
|
}
|
600
|
607
|
|
601
|
608
|
void CardReader::updir()
|
602
|
609
|
{
|
603
|
|
- if(workDirDepth > 0)
|
|
610
|
+ if (workDirDepth > 0)
|
604
|
611
|
{
|
605
|
612
|
--workDirDepth;
|
606
|
613
|
workDir = workDirParents[0];
|
607
|
|
- int d;
|
608
|
614
|
for (int d = 0; d < workDirDepth; d++)
|
609
|
615
|
workDirParents[d] = workDirParents[d+1];
|
|
616
|
+ #ifdef SDCARD_SORT_ALPHA
|
|
617
|
+ presort();
|
|
618
|
+ #endif
|
610
|
619
|
}
|
611
|
620
|
}
|
612
|
621
|
|
|
622
|
+#ifdef SDCARD_SORT_ALPHA
|
|
623
|
+
|
|
624
|
+/**
|
|
625
|
+ * Get the name of a file in the current directory by sort-index
|
|
626
|
+ */
|
|
627
|
+void CardReader::getfilename_sorted(const uint8_t nr) {
|
|
628
|
+ #if SORT_USES_MORE_RAM
|
|
629
|
+ getfilename(nr < sort_count ? sort_order[nr] : nr);
|
|
630
|
+ #else
|
|
631
|
+ getfilename(nr < SORT_LIMIT ? sort_order[nr] : nr);
|
|
632
|
+ #endif
|
|
633
|
+}
|
|
634
|
+
|
|
635
|
+/**
|
|
636
|
+ * Read all the files and produce a sort key
|
|
637
|
+ *
|
|
638
|
+ * We can do this in 3 ways...
|
|
639
|
+ * - Minimal RAM: Read two filenames at a time sorting along...
|
|
640
|
+ * - Some RAM: Buffer the directory and return filenames from RAM
|
|
641
|
+ * - Some RAM: Buffer the directory just for this sort
|
|
642
|
+ */
|
|
643
|
+void CardReader::presort()
|
|
644
|
+{
|
|
645
|
+ #if SORT_USES_MORE_RAM
|
|
646
|
+ flush_presort();
|
|
647
|
+ #endif
|
|
648
|
+
|
|
649
|
+ uint16_t fileCnt = getnrfilenames();
|
|
650
|
+ if (fileCnt > 0) {
|
|
651
|
+
|
|
652
|
+ if (fileCnt > SORT_LIMIT) fileCnt = SORT_LIMIT;
|
|
653
|
+
|
|
654
|
+ #if SORT_USES_MORE_RAM
|
|
655
|
+ sortnames = malloc(fileCnt * sizeof(char*));
|
|
656
|
+ sort_count = fileCnt;
|
|
657
|
+ #elif SORT_USES_RAM
|
|
658
|
+ char *sortnames[fileCnt];
|
|
659
|
+ #if FOLDER_SORTING != 0
|
|
660
|
+ uint8_t isdir[fileCnt];
|
|
661
|
+ #endif
|
|
662
|
+ #else
|
|
663
|
+ char sortname[LONG_FILENAME_LENGTH+1];
|
|
664
|
+ #endif
|
|
665
|
+
|
|
666
|
+ if (fileCnt > 1) {
|
|
667
|
+
|
|
668
|
+ // Init sort order [and get filenames]
|
|
669
|
+ for (int i=0; i<fileCnt; i++) {
|
|
670
|
+ int byte=i/8, bit=1<<(i%8);
|
|
671
|
+ sort_order[i] = i;
|
|
672
|
+ #if SORT_USES_RAM
|
|
673
|
+ getfilename(i);
|
|
674
|
+ char *name = diveFilename[0] ? diveFilename : filename;
|
|
675
|
+ // SERIAL_ECHOPGM("--- ");
|
|
676
|
+ // SERIAL_ECHOLN(name);
|
|
677
|
+ sortnames[i] = (char*)malloc(strlen(name) + 1);
|
|
678
|
+ strcpy(sortnames[i], name);
|
|
679
|
+ #if FOLDER_SORTING != 0
|
|
680
|
+ isdir[i] = filenameIsDir;
|
|
681
|
+ #endif
|
|
682
|
+ #endif
|
|
683
|
+ }
|
|
684
|
+
|
|
685
|
+ // Bubble Sort
|
|
686
|
+ for (uint8_t i=fileCnt; --i;) {
|
|
687
|
+ bool cmp, didSwap = false;
|
|
688
|
+ for (uint8_t j=0; j<i; ++j) {
|
|
689
|
+ int s1 = j, s2 = j+1, o1 = sort_order[s1], o2 = sort_order[s2];
|
|
690
|
+ #if SORT_USES_RAM
|
|
691
|
+ #if FOLDER_SORTING != 0
|
|
692
|
+ cmp = (isdir[o1] == isdir[o2]) ? (strcasecmp(sortnames[o1], sortnames[o2]) > 0) : isdir[FOLDER_SORTING > 0 ? o1 : o2];
|
|
693
|
+ #else
|
|
694
|
+ cmp = strcasecmp(sortnames[o1], sortnames[o2]) > 0);
|
|
695
|
+ #endif
|
|
696
|
+ #else
|
|
697
|
+ getfilename(o1);
|
|
698
|
+ #if FOLDER_SORTING != 0
|
|
699
|
+ bool dir1 = filenameIsDir;
|
|
700
|
+ #endif
|
|
701
|
+ char *name = diveFilename[0] ? diveFilename : filename;
|
|
702
|
+ strcpy(sortname, name);
|
|
703
|
+ getfilename(o2);
|
|
704
|
+ name = diveFilename[0] ? diveFilename : filename;
|
|
705
|
+ #if FOLDER_SORTING != 0
|
|
706
|
+ cmp = (dir1 == filenameIsDir) ? (strcasecmp(sortname, name) > 0) : (FOLDER_SORTING > 0 ? dir1 : !dir1);
|
|
707
|
+ #else
|
|
708
|
+ cmp = strcasecmp(sortname, name) > 0);
|
|
709
|
+ #endif
|
|
710
|
+ #endif
|
|
711
|
+ if (cmp) {
|
|
712
|
+ // SERIAL_ECHOPGM("Swap ");
|
|
713
|
+ // SERIAL_ECHOLN(sortnames[o1]);
|
|
714
|
+ // SERIAL_ECHOPGM(" for ");
|
|
715
|
+ // SERIAL_ECHOLN(sortnames[o2]);
|
|
716
|
+ sort_order[s1] = o2;
|
|
717
|
+ sort_order[s2] = o1;
|
|
718
|
+ didSwap = true;
|
|
719
|
+ }
|
|
720
|
+ }
|
|
721
|
+ if (!didSwap) break;
|
|
722
|
+ }
|
|
723
|
+
|
|
724
|
+ #if SORT_USES_RAM && !SORT_USES_MORE_RAM
|
|
725
|
+ for (int i=0; i < fileCnt; ++i) free(sortnames[i]);
|
|
726
|
+ #endif
|
|
727
|
+ }
|
|
728
|
+ else {
|
|
729
|
+ sort_order[0] = 0;
|
|
730
|
+ }
|
|
731
|
+
|
|
732
|
+ }
|
|
733
|
+}
|
|
734
|
+
|
|
735
|
+void CardReader::flush_presort() {
|
|
736
|
+ #if SORT_USES_MORE_RAM
|
|
737
|
+ if (sort_count > 0) {
|
|
738
|
+ for (int i=0; i < sort_count; ++i) {
|
|
739
|
+ free(sortnames[i]);
|
|
740
|
+ sort_order[i] = i;
|
|
741
|
+ }
|
|
742
|
+ free(sortnames);
|
|
743
|
+ sortnames = NULL;
|
|
744
|
+ sort_count = 0;
|
|
745
|
+ }
|
|
746
|
+ #else
|
|
747
|
+ for (int i=SORT_LIMIT; --i;) sort_order[i] = i;
|
|
748
|
+ #endif
|
|
749
|
+}
|
|
750
|
+
|
|
751
|
+#endif
|
613
|
752
|
|
614
|
753
|
void CardReader::printingHasFinished()
|
615
|
754
|
{
|