portability/file_system.hpp

    1: #ifndef STLPLUS_FILE_SYSTEM
    2: #define STLPLUS_FILE_SYSTEM
    3: ////////////////////////////////////////////////////////////////////////////////
    4: 
    5: //   Author:    Andy Rushton
    6: //   Copyright: (c) Andy Rushton, 2007
    7: //   License:   BSD License, see ../docs/license.html
    8: 
    9: //   Simplified access to the File system
   10: 
   11: //   All file system access and filename manipulation should be done
   12: //   with this package. Then it is only necessary to port this package
   13: //   to port all file handling.
   14: 
   15: ////////////////////////////////////////////////////////////////////////////////
   16: #include "portability_fixes.hpp"
   17: #include <string>
   18: #include <vector>
   19: #include <time.h>
   20: ////////////////////////////////////////////////////////////////////////////////
   21: 
   22: namespace stlplus
   23: {
   24: 
   25:   ////////////////////////////////////////////////////////////////////////////////
   26:   // implement string comparison of paths - Unix is case-sensitive, Windows is case-insensitive
   27: 
   28:   bool path_compare(const std::string& l, const std::string& r);
   29: 
   30:   ////////////////////////////////////////////////////////////////////////////////
   31:   // classifying functions
   32: 
   33:   bool is_present(const std::string& thing);
   34:   bool is_folder(const std::string& thing);
   35:   bool is_file(const std::string& thing);
   36: 
   37:   ////////////////////////////////////////////////////////////////////////////////
   38:   // file functions
   39: 
   40:   bool file_exists(const std::string& filespec);
   41:   bool file_readable(const std::string& filespec);
   42:   bool file_writable(const std::string& filespec);
   43:   size_t file_size(const std::string& filespec);
   44:   bool file_delete(const std::string& filespec);
   45:   bool file_rename (const std::string& old_filespec, const std::string& new_filespec);
   46:   bool file_move (const std::string& old_filespec, const std::string& new_filespec);
   47:   bool file_copy (const std::string& old_filespec, const std::string& new_filespec);
   48: 
   49:   // Read-only versus read-write control. This is equivalent to chmod on Unix,
   50:   // but I've insulated the user from the low-level routine because of
   51:   // differences in the OSs' interpretation of the mode parameter. I've also
   52:   // defined a new set of constants to control this, again because of
   53:   // inconsistencies. The idea is to combine the constants as bit-masks so as to
   54:   // build up a set of permissions. The modes are ORed together to build up a
   55:   // set of permissions and then ANDed with a mask to control which people have
   56:   // that permission. Permissions can be ORed together too. So, for example, to
   57:   // give the owner read-write access and all others only read access, you would
   58:   // use the expression:
   59:   //   ((read_mode | write_mode) & owner_mask) | (read_mode & (group_mask | other_mask))
   60:   // This can be simplified by using combined modes and combined masks to:
   61:   //   (read_write_mode & owner_mask) | (read_mode & non_owner_mask)
   62: 
   63:   // basic modes
   64:   extern const int read_mode;
   65:   extern const int write_mode;
   66:   extern const int execute_mode;
   67:   // combined modes
   68:   extern const int none_mode;
   69:   extern const int read_write_mode;
   70:   extern const int all_mode;
   71:   // basic users
   72:   extern const int owner_mask;
   73:   extern const int group_mask;
   74:   extern const int other_mask;
   75:   // combined users
   76:   extern const int non_owner_mask;
   77:   extern const int all_mask;
   78:   // common settings
   79:   extern const int read_mode_all;
   80:   extern const int read_write_mode_owner_read_mode_all;
   81:   extern const int read_mode_owner_only;
   82:   extern const int read_write_mode_owner_only;
   83:   // the function itself
   84:   bool file_set_mode(const std::string& filespec, int mode);
   85: 
   86:   // get the file's time stamps as a time_t - see the stlplus time.hpp package
   87:   time_t file_created(const std::string& filespec);
   88:   time_t file_modified(const std::string& filespec);
   89:   time_t file_accessed(const std::string& filespec);
   90: 
   91:   // platform-specific string handling to combine a directory and filename into a path
   92:   std::string create_filespec(const std::string& folder, const std::string& filename);
   93:   std::string create_filespec(const std::string& folder, const std::string& basename, const std::string& extension);
   94:   std::string create_filename(const std::string& basename, const std::string& extension);
   95: 
   96:   ////////////////////////////////////////////////////////////////////////////////
   97:   // folder functions
   98: 
   99:   bool folder_create(const std::string& folder);
  100:   bool folder_exists(const std::string& folder);
  101:   bool folder_readable(const std::string& folder);
  102:   bool folder_writable(const std::string& folder);
  103:   bool folder_delete(const std::string& folder, bool recurse = false);
  104:   bool folder_rename (const std::string& old_directory, const std::string& new_directory);
  105:   bool folder_empty(const std::string& folder);
  106: 
  107:   bool folder_set_current(const std::string& folder);
  108:   std::string folder_current(void);
  109:   std::string folder_current_full(void);
  110:   std::string folder_home(void);
  111:   std::string folder_down(const std::string& folder, const std::string& subfolder);
  112:   std::string folder_up(const std::string& folder, unsigned levels = 1);
  113: 
  114:   std::vector<std::string> folder_subdirectories(const std::string& folder);
  115:   std::vector<std::string> folder_files(const std::string& folder);
  116:   std::vector<std::string> folder_all(const std::string& folder);
  117:   std::vector<std::string> folder_wildcard(const std::string& folder, const std::string& wildcard, bool subdirs = true, bool files = true);
  118: 
  119:   ////////////////////////////////////////////////////////////////////////////////
  120:   // path functions
  121: 
  122:   bool is_full_path(const std::string& path);
  123:   bool is_relative_path(const std::string& path);
  124: 
  125:   // convert to a full path relative to the root path
  126:   std::string folder_to_path(const std::string& root, const std::string& folder);
  127:   std::string filespec_to_path(const std::string& root, const std::string& filespec);
  128: 
  129:   // convert to a full path relative to the current working directory
  130:   std::string folder_to_path(const std::string& folder);
  131:   std::string filespec_to_path(const std::string& filespec);
  132: 
  133:   // convert to a relative path relative to the root path
  134:   std::string folder_to_relative_path(const std::string& root, const std::string& folder);
  135:   std::string filespec_to_relative_path(const std::string& root, const std::string& filespec);
  136: 
  137:   // convert to a relative path relative to the current working directory
  138:   std::string folder_to_relative_path(const std::string& folder);
  139:   std::string filespec_to_relative_path(const std::string& filespec);
  140: 
  141:   // append a folder separator to the path to make it absolutely clear that it is a folder
  142:   std::string folder_append_separator(const std::string& folder);
  143: 
  144:   ////////////////////////////////////////////////////////////////////////////////
  145:   // access functions split a filespec into its elements
  146: 
  147:   std::string basename_part(const std::string& filespec);
  148:   std::string filename_part(const std::string& filespec);
  149:   std::string extension_part(const std::string& filespec);
  150:   std::string folder_part(const std::string& filespec);
  151: 
  152:   // split a path into a vector of elements - i.e. split at the folder separator
  153:   std::vector<std::string> folder_elements(const std::string& folder);
  154:   std::vector<std::string> filespec_elements(const std::string& filespec);
  155: 
  156:   ////////////////////////////////////////////////////////////////////////////////
  157:   // Path lookup functions
  158: 
  159: #ifdef MSWINDOWS
  160: #define PATH_SPLITTER ";"
  161: #else
  162: #define PATH_SPLITTER ":"
  163: #endif
  164: 
  165:   // The lookup normally carried out by the shell to find a command in a
  166:   // directory in the PATH. Give this function the name of a command and it
  167:   // will return the full path. It returns an empty string on failure.
  168:   std::string path_lookup (const std::string& command);
  169: 
  170:   // Generalised form of the above, takes a second argument
  171:   // - the list to search. This can be used to do other path lookups,
  172:   // such as LD_LIBRARY_PATH. The third argument specifies the splitter -
  173:   // the default value of PATH_SPLITTER is appropriate for environment variables.
  174:   std::string lookup (const std::string& file, const std::string& path, const std::string& splitter = PATH_SPLITTER);
  175: 
  176:   // utility function for finding the folder that contains the current executable
  177:   // the argument is the argv[0] parameter passed to main
  178:   std::string install_path(const std::string& argv0);
  179: 
  180:   ////////////////////////////////////////////////////////////////////////////////
  181: 
  182: } // end namespace stlplus
  183: 
  184: #endif