32 #define WIN32_LEAN_AND_MEAN
35 #pragma warning (disable : 4996)
46 #define _TINYDIR_PATH_MAX 4096
49 #define _TINYDIR_PATH_EXTRA 2
51 #define _TINYDIR_PATH_EXTRA 0
53 #define _TINYDIR_FILENAME_MAX 256
56 #define _TINYDIR_FUNC static __inline
58 #define _TINYDIR_FUNC static __inline__
62 #if defined(_TINYDIR_MALLOC) && defined(_TINYDIR_FREE)
63 #elif !defined(_TINYDIR_MALLOC) && !defined(_TINYDIR_FREE)
65 #error "Either define both alloc and free or none of them!"
68 #if !defined(_TINYDIR_MALLOC)
69 #define _TINYDIR_MALLOC(_size) malloc(_size)
70 #define _TINYDIR_FREE(_ptr) free(_ptr)
75 char path[_TINYDIR_PATH_MAX];
76 char name[_TINYDIR_FILENAME_MAX];
89 char path[_TINYDIR_PATH_MAX];
107 int tinydir_open(
tinydir_dir *dir,
const char *path);
109 int tinydir_open_sorted(
tinydir_dir *dir,
const char *path);
120 int tinydir_open_subdir_n(
tinydir_dir *dir,
size_t i);
125 int _tinydir_file_cmp(
const void *a,
const void *b);
131 int tinydir_open(
tinydir_dir *dir,
const char *path)
133 if (dir == NULL || path == NULL || strlen(path) == 0)
138 if (strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX)
140 errno = ENAMETOOLONG;
147 dir->_h = INVALID_HANDLE_VALUE;
153 strcpy(dir->path, path);
155 strcat(dir->path,
"\\*");
156 dir->_h = FindFirstFileA(dir->path, &dir->_f);
157 dir->path[strlen(dir->path) - 2] =
'\0';
158 if (dir->_h == INVALID_HANDLE_VALUE)
160 dir->_d = opendir(path);
171 dir->_e = readdir(dir->_d);
186 int tinydir_open_sorted(
tinydir_dir *dir,
const char *path)
190 if (tinydir_open(dir, path) == -1)
194 while (dir->has_next)
197 if (tinydir_next(dir) == -1)
204 if (tinydir_open(dir, path) == -1)
210 dir->_files = (
tinydir_file *)_TINYDIR_MALLOC(
sizeof *dir->_files * n_files);
211 if (dir->_files == NULL)
216 while (dir->has_next)
221 p_file = &dir->_files[dir->n_files - 1];
222 if (tinydir_readfile(dir, p_file) == -1)
227 if (tinydir_next(dir) == -1)
234 if (dir->n_files == n_files)
240 qsort(dir->_files, dir->n_files,
sizeof(
tinydir_file), _tinydir_file_cmp);
257 memset(dir->path, 0,
sizeof(dir->path));
260 if (dir->_files != NULL)
262 _TINYDIR_FREE(dir->_files);
266 if (dir->_h != INVALID_HANDLE_VALUE)
270 dir->_h = INVALID_HANDLE_VALUE;
296 if (FindNextFileA(dir->_h, &dir->_f) == 0)
298 dir->_e = readdir(dir->_d);
304 if (GetLastError() != ERROR_SUCCESS &&
305 GetLastError() != ERROR_NO_MORE_FILES)
320 if (dir == NULL || file == NULL)
326 if (dir->_h == INVALID_HANDLE_VALUE)
334 if (strlen(dir->path) +
341 ) + 1 + _TINYDIR_PATH_EXTRA >=
345 errno = ENAMETOOLONG;
354 ) >= _TINYDIR_FILENAME_MAX)
356 errno = ENAMETOOLONG;
360 strcpy(file->path, dir->path);
361 strcat(file->path,
"/");
369 strcat(file->path, file->name);
371 if (stat(file->path, &file->_s) == -1)
376 _tinydir_get_ext(file);
380 !!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
382 S_ISDIR(file->_s.st_mode);
386 !!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) ||
388 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) &&
389 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
390 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) &&
391 #ifdef FILE_ATTRIBUTE_INTEGRITY_STREAM
392 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_INTEGRITY_STREAM) &&
394 #ifdef FILE_ATTRIBUTE_NO_SCRUB_DATA
395 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NO_SCRUB_DATA) &&
397 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) &&
398 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY));
400 S_ISREG(file->_s.st_mode);
409 if (dir == NULL || file == NULL)
414 if (i >= dir->n_files)
421 _tinydir_get_ext(file);
427 int tinydir_open_subdir_n(
tinydir_dir *dir,
size_t i)
429 char path[_TINYDIR_PATH_MAX];
435 if (i >= dir->n_files || !dir->_files[i].is_dir)
441 strcpy(path, dir->_files[i].path);
443 if (tinydir_open_sorted(dir, path) == -1)
453 int tinydir_file_open(
tinydir_file *file,
const char *path)
458 char dir_name_buf[_TINYDIR_PATH_MAX];
459 char file_name_buf[_TINYDIR_FILENAME_MAX];
463 char drive_buf[_TINYDIR_PATH_MAX];
464 char ext_buf[_TINYDIR_FILENAME_MAX];
467 if (file == NULL || path == NULL || strlen(path) == 0)
472 if (strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX)
474 errno = ENAMETOOLONG;
482 drive_buf,
sizeof drive_buf,
483 dir_name_buf,
sizeof dir_name_buf,
484 file_name_buf,
sizeof file_name_buf,
485 ext_buf,
sizeof ext_buf))
491 strcat(drive_buf, dir_name_buf);
492 dir_name = drive_buf;
494 strcat(file_name_buf, ext_buf);
495 base_name = file_name_buf;
497 strcpy(dir_name_buf, path);
498 dir_name = dirname(dir_name_buf);
499 strcpy(file_name_buf, path);
500 base_name = basename(file_name_buf);
504 if (tinydir_open(&dir, dir_name) == -1)
512 if (tinydir_readfile(&dir, file) == -1)
517 if (strcmp(file->name, base_name) == 0)
539 char *period = strrchr(file->name,
'.');
542 file->extension = &(file->name[strlen(file->name)]);
546 file->extension = period + 1;
551 int _tinydir_file_cmp(
const void *a,
const void *b)
555 if (fa->is_dir != fb->is_dir)
557 return -(fa->is_dir - fb->is_dir);
559 return strncmp(fa->name, fb->name, _TINYDIR_FILENAME_MAX);
defined(_TINYDIR_MALLOC)
Definition: tinydir.h:73