#include "util/FileUtils.hpp" #ifndef _WIN32 #include #include #include #else #define WIN32_MEAN_AND_LEAN #include #include "util/win32/errormsg.hpp" #include "win32/tcharutils.h" #endif #include #include #include #include using namespace std; #ifndef _WIN32 static vector directory_entries_unix( const string &dir, bool absolute, bool recursive ) { vector files; DIR *d = opendir( dir.c_str( ) ); if( d == NULL ) { ostringstream ss; ss << "opendir failed with '" << dir << "': " << strerror( errno ); throw runtime_error( ss.str( ) ); } struct dirent *entry = readdir( d ); while( entry != NULL ) { if( entry->d_type == DT_DIR ) { if( strcmp( entry->d_name, "." ) == 0 || strcmp( entry->d_name, ".." ) == 0 ) { entry = readdir( d ); continue; } if( recursive ) { ostringstream ss; ss << dir << "/" << entry->d_name; vector subfiles = directory_entries_unix( ss.str( ), absolute, recursive ); files.insert( files.end( ), subfiles.begin( ), subfiles.end( ) ); } } else if( entry->d_type == DT_REG ) { if( absolute ) { ostringstream ss; ss << dir << "/" << entry->d_name; files.push_back( ss.str( ) ); } else { files.push_back( string( entry->d_name ) ); } } entry = readdir( d ); } closedir( d ); return files; } #endif #ifdef _WIN32 static vector directory_entries_win32( const string &dir, bool absolute, bool recursive ) { vector files; wstringstream wpath; wpath << utf8toucs2( dir ) << L"\\*"; WIN32_FIND_DATAW fd; HANDLE h = FindFirstFileW( wpath.str( ).c_str( ), &fd ); if( h == INVALID_HANDLE_VALUE ) { DWORD err = GetLastError( ); if( err == ERROR_NO_MORE_FILES ) { FindClose( h ); return files; } ostringstream ss; ss << "FindFirstFileW failed with '" << dir << "': " << getLastError( ); throw runtime_error( ss.str( ) ); } while( h != INVALID_HANDLE_VALUE ) { if( ( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) != 0 ) { if( wcscmp( fd.cFileName, L"." ) == 0 || wcscmp( fd.cFileName, L".." ) == 0 ) { goto NEXT; } if( recursive ) { ostringstream ss; ss << dir << "\\" << wchartoutf8( fd.cFileName ); vector subfiles = directory_entries_win32( ss.str( ), absolute, recursive ); files.insert( files.end( ), subfiles.begin( ), subfiles.end( ) ); } } else if( ( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) == 0 ) { if( absolute ) { ostringstream ss; ss << dir << "\\" << wchartoutf8( fd.cFileName ); files.push_back( ss.str( ) ); } else { files.push_back( string( wchartoutf8( fd.cFileName ) ) ); } } NEXT: if( !FindNextFileW( h, &fd ) ) { DWORD err = GetLastError( ); if( err == ERROR_NO_MORE_FILES ) { // finish iterating FindClose( h ); return files; } else { FindClose( h ); ostringstream ss; ss << "FindNextFileW failed with '" << dir << "': " << getLastError( ); throw runtime_error( ss.str( ) ); } } } FindClose( h ); return files; } #endif UTIL_DLL_VISIBLE vector directory_entries( const string &dir, bool absolute, bool recursive ) { #ifdef _WIN32 return directory_entries_win32( dir, absolute, recursive ); #else return directory_entries_unix( dir, absolute, recursive ); #endif }