diff options
author | Miika Pekkarinen <miipekk@ihme.org> | 2006-03-30 18:53:44 +0000 |
---|---|---|
committer | Miika Pekkarinen <miipekk@ihme.org> | 2006-03-30 18:53:44 +0000 |
commit | 3881ce94bd73ecd38855a385dadfdf16564927ca (patch) | |
tree | abe97e68d89984d80065c85de63585996486abe0 /firmware/common/dircache.c | |
parent | dc8de7ea3d1305f09323abbea9d24b1d1bb1c5cd (diff) | |
download | rockbox-3881ce94bd73ecd38855a385dadfdf16564927ca.tar.gz rockbox-3881ce94bd73ecd38855a385dadfdf16564927ca.zip |
Dircache support for simulator also.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9365 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/common/dircache.c')
-rw-r--r-- | firmware/common/dircache.c | 105 |
1 files changed, 83 insertions, 22 deletions
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c index efab37b5c4..9a0bcb631f 100644 --- a/firmware/common/dircache.c +++ b/firmware/common/dircache.c | |||
@@ -19,7 +19,6 @@ | |||
19 | 19 | ||
20 | /* TODO: | 20 | /* TODO: |
21 | - Allow cache live updating while transparent rebuild is running. | 21 | - Allow cache live updating while transparent rebuild is running. |
22 | - Fix this to work with simulator (opendir & readdir) again. | ||
23 | */ | 22 | */ |
24 | 23 | ||
25 | #include "config.h" | 24 | #include "config.h" |
@@ -111,7 +110,8 @@ static struct dircache_entry* dircache_gen_next(struct dircache_entry *ce) | |||
111 | { | 110 | { |
112 | struct dircache_entry *next_entry; | 111 | struct dircache_entry *next_entry; |
113 | 112 | ||
114 | next_entry = allocate_entry(); | 113 | if ( (next_entry = allocate_entry()) == NULL) |
114 | return NULL; | ||
115 | next_entry->up = ce->up; | 115 | next_entry->up = ce->up; |
116 | ce->next = next_entry; | 116 | ce->next = next_entry; |
117 | 117 | ||
@@ -126,7 +126,8 @@ static struct dircache_entry* dircache_gen_down(struct dircache_entry *ce) | |||
126 | { | 126 | { |
127 | struct dircache_entry *next_entry; | 127 | struct dircache_entry *next_entry; |
128 | 128 | ||
129 | next_entry = allocate_entry(); | 129 | if ( (next_entry = allocate_entry()) == NULL) |
130 | return NULL; | ||
130 | next_entry->up = ce; | 131 | next_entry->up = ce; |
131 | ce->down = next_entry; | 132 | ce->down = next_entry; |
132 | 133 | ||
@@ -164,16 +165,27 @@ static bool check_event_queue(void) | |||
164 | */ | 165 | */ |
165 | static int dircache_scan(struct travel_data *td) | 166 | static int dircache_scan(struct travel_data *td) |
166 | { | 167 | { |
168 | #ifdef SIMULATOR | ||
169 | while ( ( td->entry = readdir(td->dir) ) ) | ||
170 | #else | ||
167 | while ( (fat_getnext(td->dir, &td->entry) >= 0) && (td->entry.name[0])) | 171 | while ( (fat_getnext(td->dir, &td->entry) >= 0) && (td->entry.name[0])) |
172 | #endif | ||
168 | { | 173 | { |
169 | if (thread_enabled) | 174 | #ifdef SIMULATOR |
175 | if (!strcmp(".", td->entry->d_name) || | ||
176 | !strcmp("..", td->entry->d_name)) | ||
170 | { | 177 | { |
171 | /* Stop if we got an external signal. */ | 178 | continue; |
172 | if (check_event_queue()) | ||
173 | return -6; | ||
174 | yield(); | ||
175 | } | 179 | } |
176 | 180 | ||
181 | td->ce->attribute = td->entry->attribute; | ||
182 | td->ce->name_len = MIN(254, strlen(td->entry->d_name)) + 1; | ||
183 | td->ce->d_name = ((char *)dircache_root+dircache_size); | ||
184 | td->ce->size = td->entry->size; | ||
185 | td->ce->wrtdate = td->entry->wrtdate; | ||
186 | td->ce->wrttime = td->entry->wrttime; | ||
187 | memcpy(td->ce->d_name, td->entry->d_name, td->ce->name_len); | ||
188 | #else | ||
177 | if (!strcmp(".", td->entry.name) || | 189 | if (!strcmp(".", td->entry.name) || |
178 | !strcmp("..", td->entry.name)) | 190 | !strcmp("..", td->entry.name)) |
179 | { | 191 | { |
@@ -188,10 +200,15 @@ static int dircache_scan(struct travel_data *td) | |||
188 | td->ce->wrtdate = td->entry.wrtdate; | 200 | td->ce->wrtdate = td->entry.wrtdate; |
189 | td->ce->wrttime = td->entry.wrttime; | 201 | td->ce->wrttime = td->entry.wrttime; |
190 | memcpy(td->ce->d_name, td->entry.name, td->ce->name_len); | 202 | memcpy(td->ce->d_name, td->entry.name, td->ce->name_len); |
203 | #endif | ||
191 | dircache_size += td->ce->name_len; | 204 | dircache_size += td->ce->name_len; |
192 | entry_count++; | 205 | entry_count++; |
193 | 206 | ||
207 | #ifdef SIMULATOR | ||
208 | if (td->entry->attribute & ATTR_DIRECTORY) | ||
209 | #else | ||
194 | if (td->entry.attr & FAT_ATTR_DIRECTORY) | 210 | if (td->entry.attr & FAT_ATTR_DIRECTORY) |
211 | #endif | ||
195 | { | 212 | { |
196 | 213 | ||
197 | td->down_entry = dircache_gen_down(td->ce); | 214 | td->down_entry = dircache_gen_down(td->ce); |
@@ -200,6 +217,16 @@ static int dircache_scan(struct travel_data *td) | |||
200 | 217 | ||
201 | td->pathpos = strlen(dircache_cur_path); | 218 | td->pathpos = strlen(dircache_cur_path); |
202 | strncpy(&dircache_cur_path[td->pathpos], "/", MAX_PATH - td->pathpos - 1); | 219 | strncpy(&dircache_cur_path[td->pathpos], "/", MAX_PATH - td->pathpos - 1); |
220 | #ifdef SIMULATOR | ||
221 | strncpy(&dircache_cur_path[td->pathpos+1], td->entry->d_name, MAX_PATH - td->pathpos - 2); | ||
222 | |||
223 | td->newdir = opendir(dircache_cur_path); | ||
224 | if (td->newdir == NULL) | ||
225 | { | ||
226 | logf("Failed to opendir(): %s", dircache_cur_path); | ||
227 | return -3; | ||
228 | } | ||
229 | #else | ||
203 | strncpy(&dircache_cur_path[td->pathpos+1], td->entry.name, MAX_PATH - td->pathpos - 2); | 230 | strncpy(&dircache_cur_path[td->pathpos+1], td->entry.name, MAX_PATH - td->pathpos - 2); |
204 | 231 | ||
205 | td->newdir = *td->dir; | 232 | td->newdir = *td->dir; |
@@ -208,6 +235,7 @@ static int dircache_scan(struct travel_data *td) | |||
208 | { | 235 | { |
209 | return -3; | 236 | return -3; |
210 | } | 237 | } |
238 | #endif | ||
211 | 239 | ||
212 | td->ce = dircache_gen_next(td->ce); | 240 | td->ce = dircache_gen_next(td->ce); |
213 | if (td->ce == NULL) | 241 | if (td->ce == NULL) |
@@ -220,6 +248,16 @@ static int dircache_scan(struct travel_data *td) | |||
220 | td->ce = dircache_gen_next(td->ce); | 248 | td->ce = dircache_gen_next(td->ce); |
221 | if (td->ce == NULL) | 249 | if (td->ce == NULL) |
222 | return -5; | 250 | return -5; |
251 | |||
252 | /* When simulator is used, it's only safe to yield here. */ | ||
253 | if (thread_enabled) | ||
254 | { | ||
255 | /* Stop if we got an external signal. */ | ||
256 | if (check_event_queue()) | ||
257 | return -6; | ||
258 | yield(); | ||
259 | } | ||
260 | |||
223 | } | 261 | } |
224 | 262 | ||
225 | return 0; | 263 | return 0; |
@@ -228,7 +266,11 @@ static int dircache_scan(struct travel_data *td) | |||
228 | /** | 266 | /** |
229 | * Recursively scan the hard disk and build the cache. | 267 | * Recursively scan the hard disk and build the cache. |
230 | */ | 268 | */ |
269 | #ifdef SIMULATOR | ||
270 | static int dircache_travel(DIR *dir, struct dircache_entry *ce) | ||
271 | #else | ||
231 | static int dircache_travel(struct fat_dir *dir, struct dircache_entry *ce) | 272 | static int dircache_travel(struct fat_dir *dir, struct dircache_entry *ce) |
273 | #endif | ||
232 | { | 274 | { |
233 | int depth = 0; | 275 | int depth = 0; |
234 | int result; | 276 | int result; |
@@ -245,10 +287,15 @@ static int dircache_travel(struct fat_dir *dir, struct dircache_entry *ce) | |||
245 | case 0: /* Leaving the current directory. */ | 287 | case 0: /* Leaving the current directory. */ |
246 | /* Add the standard . and .. entries. */ | 288 | /* Add the standard . and .. entries. */ |
247 | ce = dir_recursion[depth].ce; | 289 | ce = dir_recursion[depth].ce; |
248 | ce->attribute = FAT_ATTR_DIRECTORY; | ||
249 | ce->d_name = "."; | 290 | ce->d_name = "."; |
250 | ce->name_len = 2; | 291 | ce->name_len = 2; |
292 | #ifdef SIMULATOR | ||
293 | closedir(dir_recursion[depth].dir); | ||
294 | ce->attribute = ATTR_DIRECTORY; | ||
295 | #else | ||
296 | ce->attribute = FAT_ATTR_DIRECTORY; | ||
251 | ce->startcluster = dir_recursion[depth].dir->file.firstcluster; | 297 | ce->startcluster = dir_recursion[depth].dir->file.firstcluster; |
298 | #endif | ||
252 | ce->size = 0; | 299 | ce->size = 0; |
253 | ce->down = dir_recursion[depth].first; | 300 | ce->down = dir_recursion[depth].first; |
254 | 301 | ||
@@ -264,10 +311,14 @@ static int dircache_travel(struct fat_dir *dir, struct dircache_entry *ce) | |||
264 | logf("memory allocation error"); | 311 | logf("memory allocation error"); |
265 | return -3; | 312 | return -3; |
266 | } | 313 | } |
314 | #ifdef SIMULATOR | ||
315 | ce->attribute = ATTR_DIRECTORY; | ||
316 | #else | ||
267 | ce->attribute = FAT_ATTR_DIRECTORY; | 317 | ce->attribute = FAT_ATTR_DIRECTORY; |
318 | ce->startcluster = dir_recursion[depth].dir->file.firstcluster; | ||
319 | #endif | ||
268 | ce->d_name = ".."; | 320 | ce->d_name = ".."; |
269 | ce->name_len = 3; | 321 | ce->name_len = 3; |
270 | ce->startcluster = dir_recursion[depth].dir->file.firstcluster; | ||
271 | ce->size = 0; | 322 | ce->size = 0; |
272 | ce->down = dir_recursion[depth].first; | 323 | ce->down = dir_recursion[depth].first; |
273 | 324 | ||
@@ -280,8 +331,12 @@ static int dircache_travel(struct fat_dir *dir, struct dircache_entry *ce) | |||
280 | logf("Too deep directory structure"); | 331 | logf("Too deep directory structure"); |
281 | return -2; | 332 | return -2; |
282 | } | 333 | } |
283 | 334 | ||
335 | #ifdef SIMULATOR | ||
336 | dir_recursion[depth].dir = dir_recursion[depth-1].newdir; | ||
337 | #else | ||
284 | dir_recursion[depth].dir = &dir_recursion[depth-1].newdir; | 338 | dir_recursion[depth].dir = &dir_recursion[depth-1].newdir; |
339 | #endif | ||
285 | dir_recursion[depth].first = dir_recursion[depth-1].down_entry; | 340 | dir_recursion[depth].first = dir_recursion[depth-1].down_entry; |
286 | dir_recursion[depth].ce = dir_recursion[depth-1].down_entry; | 341 | dir_recursion[depth].ce = dir_recursion[depth-1].down_entry; |
287 | break ; | 342 | break ; |
@@ -448,7 +503,11 @@ int dircache_save(const char *path) | |||
448 | */ | 503 | */ |
449 | static int dircache_do_rebuild(void) | 504 | static int dircache_do_rebuild(void) |
450 | { | 505 | { |
451 | struct fat_dir dir; | 506 | #ifdef SIMULATOR |
507 | DIR *pdir; | ||
508 | #else | ||
509 | struct fat_dir dir, *pdir; | ||
510 | #endif | ||
452 | unsigned int start_tick; | 511 | unsigned int start_tick; |
453 | int i; | 512 | int i; |
454 | 513 | ||
@@ -456,25 +515,27 @@ static int dircache_do_rebuild(void) | |||
456 | start_tick = current_tick; | 515 | start_tick = current_tick; |
457 | dircache_initializing = true; | 516 | dircache_initializing = true; |
458 | 517 | ||
518 | #ifdef SIMULATOR | ||
519 | pdir = opendir("/"); | ||
520 | if (pdir == NULL) | ||
521 | { | ||
522 | logf("Failed to open rootdir"); | ||
523 | return -3; | ||
524 | } | ||
525 | #else | ||
459 | if ( fat_opendir(IF_MV2(volume,) &dir, 0, NULL) < 0 ) { | 526 | if ( fat_opendir(IF_MV2(volume,) &dir, 0, NULL) < 0 ) { |
460 | logf("Failed opening root dir"); | 527 | logf("Failed opening root dir"); |
461 | dircache_initializing = false; | 528 | dircache_initializing = false; |
462 | return -3; | 529 | return -3; |
463 | } | 530 | } |
464 | 531 | pdir = &dir; | |
465 | //return -5; | 532 | #endif |
466 | /* dir = opendir("/"); | ||
467 | if (dir == NULL) | ||
468 | { | ||
469 | logf("failed to open rootdir"); | ||
470 | return -1; | ||
471 | }*/ | ||
472 | 533 | ||
473 | memset(dircache_cur_path, 0, MAX_PATH); | 534 | memset(dircache_cur_path, 0, MAX_PATH); |
474 | dircache_size = sizeof(struct dircache_entry); | 535 | dircache_size = sizeof(struct dircache_entry); |
475 | 536 | ||
476 | cpu_boost(true); | 537 | cpu_boost(true); |
477 | if (dircache_travel(&dir, dircache_root) < 0) | 538 | if (dircache_travel(pdir, dircache_root) < 0) |
478 | { | 539 | { |
479 | logf("dircache_travel failed"); | 540 | logf("dircache_travel failed"); |
480 | cpu_boost(false); | 541 | cpu_boost(false); |