32 #define WIN32_LEAN_AND_MEAN
34 #pragma warning (disable : 4996)
44 #define _TINYDIR_PATH_MAX 4096
47 #define _TINYDIR_PATH_EXTRA 2
49 #define _TINYDIR_PATH_EXTRA 0
51 #define _TINYDIR_FILENAME_MAX 256
54 #define _TINYDIR_FUNC static __inline
56 #define _TINYDIR_FUNC static __inline__
61 char path[_TINYDIR_PATH_MAX];
62 char name[_TINYDIR_FILENAME_MAX];
75 char path[_TINYDIR_PATH_MAX];
93 int tinydir_open(
tinydir_dir *dir,
const char *path);
95 int tinydir_open_sorted(
tinydir_dir *dir,
const char *path);
106 int tinydir_open_subdir_n(
tinydir_dir *dir,
size_t i);
111 int _tinydir_file_cmp(
const void *a,
const void *b);
117 int tinydir_open(
tinydir_dir *dir,
const char *path)
119 if (dir == NULL || path == NULL || strlen(path) == 0)
124 if (strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX)
126 errno = ENAMETOOLONG;
133 dir->_h = INVALID_HANDLE_VALUE;
139 strcpy(dir->path, path);
141 strcat(dir->path,
"\\*");
142 dir->_h = FindFirstFile(dir->path, &dir->_f);
143 dir->path[strlen(dir->path) - 2] =
'\0';
144 if (dir->_h == INVALID_HANDLE_VALUE)
146 dir->_d = opendir(path);
157 dir->_e = readdir(dir->_d);
172 int tinydir_open_sorted(
tinydir_dir *dir,
const char *path)
176 if (tinydir_open(dir, path) == -1)
180 while (dir->has_next)
183 if (tinydir_next(dir) == -1)
190 if (tinydir_open(dir, path) == -1)
196 dir->_files = (
tinydir_file *)malloc(
sizeof *dir->_files * n_files);
197 if (dir->_files == NULL)
202 while (dir->has_next)
207 p_file = &dir->_files[dir->n_files - 1];
208 if (tinydir_readfile(dir, p_file) == -1)
213 if (tinydir_next(dir) == -1)
220 if (dir->n_files == n_files)
226 qsort(dir->_files, dir->n_files,
sizeof(
tinydir_file), _tinydir_file_cmp);
243 memset(dir->path, 0,
sizeof(dir->path));
246 if (dir->_files != NULL)
252 if (dir->_h != INVALID_HANDLE_VALUE)
256 dir->_h = INVALID_HANDLE_VALUE;
282 if (FindNextFile(dir->_h, &dir->_f) == 0)
284 dir->_e = readdir(dir->_d);
290 if (GetLastError() != ERROR_SUCCESS &&
291 GetLastError() != ERROR_NO_MORE_FILES)
306 if (dir == NULL || file == NULL)
312 if (dir->_h == INVALID_HANDLE_VALUE)
320 if (strlen(dir->path) +
327 ) + 1 + _TINYDIR_PATH_EXTRA >=
331 errno = ENAMETOOLONG;
340 ) >= _TINYDIR_FILENAME_MAX)
342 errno = ENAMETOOLONG;
346 strcpy(file->path, dir->path);
347 strcat(file->path,
"/");
355 strcat(file->path, file->name);
357 if (stat(file->path, &file->_s) == -1)
362 _tinydir_get_ext(file);
366 !!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
368 S_ISDIR(file->_s.st_mode);
372 !!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) ||
374 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) &&
375 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
376 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) &&
377 #ifdef FILE_ATTRIBUTE_INTEGRITY_STREAM
378 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_INTEGRITY_STREAM) &&
380 #ifdef FILE_ATTRIBUTE_NO_SCRUB_DATA
381 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NO_SCRUB_DATA) &&
383 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) &&
384 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY));
386 S_ISREG(file->_s.st_mode);
395 if (dir == NULL || file == NULL)
400 if (i >= dir->n_files)
407 _tinydir_get_ext(file);
413 int tinydir_open_subdir_n(
tinydir_dir *dir,
size_t i)
415 char path[_TINYDIR_PATH_MAX];
421 if (i >= dir->n_files || !dir->_files[i].is_dir)
427 strcpy(path, dir->_files[i].path);
429 if (tinydir_open_sorted(dir, path) == -1)
439 int tinydir_file_open(
tinydir_file *file,
const char *path)
444 char dir_name_buf[_TINYDIR_PATH_MAX];
445 char file_name_buf[_TINYDIR_FILENAME_MAX];
449 char drive_buf[_TINYDIR_PATH_MAX];
450 char ext_buf[_TINYDIR_FILENAME_MAX];
453 if (file == NULL || path == NULL || strlen(path) == 0)
458 if (strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX)
460 errno = ENAMETOOLONG;
468 drive_buf,
sizeof drive_buf,
469 dir_name_buf,
sizeof dir_name_buf,
470 file_name_buf,
sizeof file_name_buf,
471 ext_buf,
sizeof ext_buf))
477 strcat(drive_buf, dir_name_buf);
478 dir_name = drive_buf;
480 strcat(file_name_buf, ext_buf);
481 base_name = file_name_buf;
483 strcpy(dir_name_buf, path);
484 dir_name = dirname(dir_name_buf);
485 strcpy(file_name_buf, path);
486 base_name = basename(file_name_buf);
490 if (tinydir_open(&dir, dir_name) == -1)
498 if (tinydir_readfile(&dir, file) == -1)
503 if (strcmp(file->name, base_name) == 0)
525 char *period = strrchr(file->name,
'.');
528 file->extension = &(file->name[strlen(file->name)]);
532 file->extension = period + 1;
537 int _tinydir_file_cmp(
const void *a,
const void *b)
541 if (fa->is_dir != fb->is_dir)
543 return -(fa->is_dir - fb->is_dir);
545 return strncmp(fa->name, fb->name, _TINYDIR_FILENAME_MAX);