#ifndef STIM_FILENAME_H #define STIM_FILENAME_H #include /* defines FILENAME_MAX */ #ifdef _WIN32 #include #include #define GetCurrentDir _getcwd #define STIM_FILENAME_DIV '\\' #else #include #define GetCurrentDir getcwd #define STIM_FILENAME_DIV '/' #endif #include #include #include #include #include #include #include #include "../parser/parser.h" #ifdef BOOST_PRECOMPILED #include #endif namespace stim{ //filename class designed to work with both Windows and Unix class filename{ private: void init(){ absolute = false; } protected: std::string drive; //drive letter (for Windows) std::vector path; //directory hierarchy std::string prefix; //file prefix (without extension) std::string ext; //file extension bool absolute; //filename is an absolute path //replaces win32 dividers with the Linux standard std::string unix_div(std::string s) { std::replace( s.begin(), s.end(), '\\', '/'); return s; } //break up a filename into a prefix and extension void parse_name(std::string fname){ //find the extension size_t xpos = fname.find_last_of('.'); //find the position of the extension period (if there is one) if(xpos != std::string::npos){ //split the prefix and extension prefix = fname.substr(0, xpos); ext = fname.substr(xpos + 1); } else prefix = fname; } //parse a file locator string void parse(std::string loc){ loc = unix_div(loc); //determine the drive (if Windows) drive = ""; #ifdef _WIN32 //if the second character is a colon, the character right before it is the drive if(loc[1] == ':'){ absolute = true; //this is an absolute path drive = loc[0]; //copy the drive letter loc = loc.substr(3); //remove the drive information from the locator string } #else if(loc[0] == STIM_FILENAME_DIV){ absolute = true; loc = loc.substr(1); } #endif //determine the file name std::string fname = loc.substr( loc.find_last_of('/') + 1 ); //find the file name (including extension) //parse the file name parse_name(fname); //find the directory hierarchy std::string dir = loc.substr(0, loc.find_last_of('/') + 1 ); path = stim::parser::split(dir, '/'); } public: filename(){ init(); } filename(std::string loc){ init(); parse(loc); } /// Outputs the file name (including prefix and extension) std::string get_name(){ if(prefix == "" && ext == "") return ""; else return prefix + "." + ext; } /// Output the file extension only (usually three characters after a '.') std::string get_extension(){ return ext; } /// Output the file prefix only (name before the extension) std::string get_prefix(){ return prefix; } /// Output the entire path (not including the filename) /// ex. "c:\this\is\the\directory\" std::string dir(){ std::stringstream ss; //if the path is absolute if(absolute){ //output the drive letter if in Windows #ifdef _WIN32 ss< get_list(){ //this is OS dependent, so we're starting with Windows //the Unix version requires Boost #ifdef _WIN32 stim::filename filepath(dir_fname()); //initialize filepath with the mask HANDLE hFind = INVALID_HANDLE_VALUE; //allocate data structures for looping through files WIN32_FIND_DATAA FindFileData; std::vector file_list; //initialize a list to hold all matching filenames hFind = FindFirstFileA((filepath.str().c_str()), &FindFileData); //find the first file that matches the specified file path if (hFind == INVALID_HANDLE_VALUE) { //if there are no matching files printf ("Invalid file handle. Error is %u.\n", GetLastError()); //print an error } else { std::string file_name = FindFileData.cFileName; //save the file name std::string file_path = dir(); //the file is in the specified directory, so save it stim::filename current_file(file_path + file_name); //create a stim::filename structure representing this file file_list.push_back(current_file); //push the new stim::filename to the file list // List all the other files in the directory. while (FindNextFileA(hFind, &FindFileData) != 0){ //iterate until there are no more matching files file_name = FindFileData.cFileName; //save the next file current_file = (f_name(file_name)); //append the directory file_list.push_back(current_file); //push it to the list } FindClose(hFind); //close the file data structure } return file_list; //return the list of files #elif BOOST_PRECOMPILED boost::filesystem::path p(dir()); //create a path from the current filename std::vector file_list; if(boost::filesystem::exists(p)){ if(boost::filesystem::is_directory(p)){ typedef std::vector vec; // store paths, vec v; // so we can sort them later std::copy(boost::filesystem::directory_iterator(p), boost::filesystem::directory_iterator(), back_inserter(v)); std::sort(v.begin(), v.end()); // sort, since directory iteration // is not ordered on some file systems //compare file names to the current template (look for wild cards) for (vec::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { //if the filename is a wild card *or* it matches the read file name if( prefix == "*" || prefix == (*it).filename().stem().string()){ //if the extension is a wild card *or* it matches the read file extension if( ext == "*" || "." + ext == (*it).filename().extension().string()){ file_list.push_back((*it).string()); //include it in the final list } } } } } return file_list; #else std::cout<<"ERROR: UNIX systems don't support file lists without the Boost precompiled libraries."< rel_path = stim::parser::split(rel, STIM_FILENAME_DIV); //if the relative path doesn't contain a file, add a blank string to be used as the filename if(rel[rel.size()-1] == STIM_FILENAME_DIV) rel_path.push_back(""); //create a stack representing the current absolute path std::stack > s(path); //for each token in the relative path for(int d=0; d result_path(begin, end); //create a new path to be returned stim::filename result = *this; result.path = result_path; result.set_name(rel_path.back()); return result; } /// This function replaces a wildcard in the prefix with the specified string stim::filename insert(std::string str){ stim::filename result = *this; //initialize the result filename to the current filename size_t loc = result.prefix.find('*'); //find a wild card in the string if(loc == std::string::npos) //if a wildcard isn't found result.prefix += str; //append the value to the prefix else result.prefix.replace(loc, 1, str); //replace the wildcard with the string return result; //return the result } stim::filename insert(size_t i, size_t n = 2){ std::stringstream ss; ss << std::setw(n) << std::setfill('0') << i; return insert(ss.str()); } bool is_relative(){ return !absolute; } bool is_absolute(){ return absolute; } }; } //end namespace stim #endif