1
+ #include "memcard_manager.h"
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+ #include "sd_config.h"
5
+ #include "memory_card.h"
6
+
7
+ bool is_name_valid (uint8_t * filename ) {
8
+ if (!filename )
9
+ return false;
10
+ filename = strupr (filename ); // convert to upper case
11
+ /* check .MCR extension */
12
+ uint8_t * ext = strrchr (filename , '.' );
13
+ if (!ext || strcmp (ext , ".MCR" ))
14
+ return false;
15
+ /* check that filename (excluding extension) is only digits */
16
+ uint32_t digit_char_count = strspn (filename , "0123456789" );
17
+ if (digit_char_count != strlen (filename ) - strlen (".MCR" ))
18
+ return false;
19
+ return true;
20
+ }
21
+
22
+ bool is_image_valid (uint8_t * filename ) {
23
+ if (!filename )
24
+ return false;
25
+ filename = strupr (filename ); // convert to upper case
26
+ if (!is_name_valid (filename ))
27
+ return false;
28
+ FILINFO f_info ;
29
+ FRESULT f_res = f_stat (filename , & f_info );
30
+ if (f_res != FR_OK )
31
+ return false;
32
+ if (f_info .fsize != MC_SIZE ) // check that memory card image has correct size
33
+ return false;
34
+ return true;
35
+ }
36
+
37
+ bool memcard_manager_exist (uint8_t * filename ) {
38
+ if (!filename )
39
+ return false;
40
+ return is_image_valid (filename );
41
+ }
42
+
43
+ uint32_t memcard_manager_count () {
44
+ FRESULT res ;
45
+ DIR root ;
46
+ FILINFO f_info ;
47
+ res = f_opendir (& root , "" ); // open root directory
48
+ uint32_t count = 0 ;
49
+ if (res == FR_OK ) {
50
+ while (true) {
51
+ res = f_readdir (& root , & f_info );
52
+ if (res != FR_OK || f_info .fname [0 ] == 0 ) break ;
53
+ if (!(f_info .fattrib & AM_DIR )) { // not a directory
54
+ if (is_image_valid (f_info .fname ))
55
+ ++ count ;
56
+ }
57
+ }
58
+ }
59
+ return count ;
60
+ }
61
+
62
+ uint32_t memcard_manager_get (uint32_t index , uint8_t * out_filename ) {
63
+ if (index < 0 || index > MAX_MC_IMAGES )
64
+ return MM_INDEX_OUT_OF_BOUNDS ;
65
+ uint32_t count = memcard_manager_count ();
66
+ if (index >= count )
67
+ return MM_INDEX_OUT_OF_BOUNDS ;
68
+ uint8_t * image_names = malloc (((MAX_MC_FILENAME_LEN + 1 ) * count )); // allocate space for image names
69
+ if (!image_names )
70
+ return MM_ALLOC_FAIL ; // malloc failed
71
+ /* retrive images names */
72
+ FRESULT res ;
73
+ DIR root ;
74
+ FILINFO f_info ;
75
+ res = f_opendir (& root , "" ); // open root directory
76
+ uint32_t i = 0 ;
77
+ if (res == FR_OK ) {
78
+ while (true) {
79
+ res = f_readdir (& root , & f_info );
80
+ if (res != FR_OK || f_info .fname [0 ] == 0 ) break ;
81
+ if (!(f_info .fattrib & AM_DIR )) { // not a directory
82
+ if (is_image_valid (f_info .fname )) {
83
+ strcpy (& image_names [(MAX_MC_FILENAME_LEN + 1 ) * i ], f_info .fname );
84
+ ++ i ;
85
+ }
86
+ }
87
+ }
88
+ }
89
+ /* sort names alphabetically */
90
+ qsort (image_names , count , (MAX_MC_FILENAME_LEN + 1 ), (__compar_fn_t ) strcmp );
91
+ strcpy (out_filename , & image_names [(MAX_MC_FILENAME_LEN + 1 ) * index ]);
92
+ free (image_names ); // free allocated memory
93
+ return MM_OK ;
94
+ }
95
+
96
+ uint32_t memcard_manager_get_next (uint8_t * filename , uint8_t * out_nextfile ) {
97
+ uint32_t count = memcard_manager_count ();
98
+ uint32_t buff_size = (MAX_MC_FILENAME_LEN + 1 ) * count ;
99
+ uint8_t * image_names = malloc (buff_size ); // allocate space for image names
100
+ if (!image_names )
101
+ return MM_ALLOC_FAIL ; // malloc failed
102
+ /* retrive images names */
103
+ FRESULT res ;
104
+ DIR root ;
105
+ FILINFO f_info ;
106
+ res = f_opendir (& root , "" ); // open root directory
107
+ uint32_t i = 0 ;
108
+ if (res == FR_OK ) {
109
+ while (true) {
110
+ res = f_readdir (& root , & f_info );
111
+ if (res != FR_OK || f_info .fname [0 ] == 0 ) break ;
112
+ if (!(f_info .fattrib & AM_DIR )) { // not a directory
113
+ if (is_image_valid (f_info .fname )) {
114
+ strcpy (& image_names [(MAX_MC_FILENAME_LEN + 1 ) * i ], f_info .fname );
115
+ ++ i ;
116
+ }
117
+ }
118
+ }
119
+ }
120
+ /* sort names alphabetically */
121
+ qsort (image_names , count , (MAX_MC_FILENAME_LEN + 1 ), (__compar_fn_t ) strcmp );
122
+ /* find current and return following one */
123
+ bool found = false;
124
+ for (uint32_t i = 0 ; i < buff_size ; i = i + (MAX_MC_FILENAME_LEN + 1 )) {
125
+ if (!strcmp (filename , & image_names [i ])) {
126
+ int32_t next_i = i + (MAX_MC_FILENAME_LEN + 1 );
127
+ if (next_i < buff_size ) {
128
+ strcpy (out_nextfile , & image_names [next_i ]);
129
+ found = true;
130
+ break ;
131
+ }
132
+ }
133
+ }
134
+ free (image_names ); // free allocated memory
135
+ /* return */
136
+ if (found )
137
+ return MM_OK ;
138
+ else
139
+ return MM_NO_ENTRY ;
140
+ }
141
+
142
+ uint32_t memcard_manager_get_prev (uint8_t * filename , uint8_t * out_prevfile ) {
143
+ uint32_t count = memcard_manager_count ();
144
+ uint32_t buff_size = (MAX_MC_FILENAME_LEN + 1 ) * count ;
145
+ uint8_t * image_names = malloc (buff_size ); // allocate space for image names
146
+ if (!image_names )
147
+ return MM_ALLOC_FAIL ; // malloc failed
148
+ /* retrive images names */
149
+ FRESULT res ;
150
+ DIR root ;
151
+ FILINFO f_info ;
152
+ res = f_opendir (& root , "" ); // open root directory
153
+ uint32_t i = 0 ;
154
+ if (res == FR_OK ) {
155
+ while (true) {
156
+ res = f_readdir (& root , & f_info );
157
+ if (res != FR_OK || f_info .fname [0 ] == 0 ) break ;
158
+ if (!(f_info .fattrib & AM_DIR )) { // not a directory
159
+ if (is_image_valid (f_info .fname )) {
160
+ strcpy (& image_names [(MAX_MC_FILENAME_LEN + 1 ) * i ], f_info .fname );
161
+ ++ i ;
162
+ }
163
+ }
164
+ }
165
+ }
166
+ /* sort names alphabetically */
167
+ qsort (image_names , count , (MAX_MC_FILENAME_LEN + 1 ), (__compar_fn_t ) strcmp );
168
+ /* find current and return prior one */
169
+ bool found = false;
170
+ for (uint32_t i = 0 ; i < buff_size ; i = i + (MAX_MC_FILENAME_LEN + 1 )) {
171
+ if (!strcmp (filename , & image_names [i ])) {
172
+ int32_t prev_i = i - (MAX_MC_FILENAME_LEN + 1 );
173
+ if (prev_i >= 0 ) {
174
+ strcpy (out_prevfile , & image_names [prev_i ]);
175
+ found = true;
176
+ break ;
177
+ }
178
+ }
179
+ }
180
+ free (image_names ); // free allocated memory
181
+ /* return */
182
+ if (found )
183
+ return MM_OK ;
184
+ else
185
+ return MM_NO_ENTRY ;
186
+ }
187
+
188
+ uint32_t memcard_manager_create () {
189
+
190
+ }
0 commit comments