Panda3D
|
00001 // Filename: filename.h 00002 // Created by: drose (18Jan99) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifndef FILENAME_H 00016 #define FILENAME_H 00017 00018 #include "dtoolbase.h" 00019 #include "pandaFileStream.h" 00020 #include "typeHandle.h" 00021 #include "register_type.h" 00022 #include "vector_string.h" 00023 00024 #include <assert.h> 00025 00026 class DSearchPath; 00027 00028 //////////////////////////////////////////////////////////////////// 00029 // Class : Filename 00030 // Description : The name of a file, such as a texture file or an Egg 00031 // file. Stores the full pathname, and includes 00032 // functions for extracting out the directory prefix 00033 // part and the file extension and stuff. 00034 // 00035 // A Filename is also aware of the mapping between the 00036 // Unix-like filename convention we use internally, and 00037 // the local OS's specific filename convention, and it 00038 // knows how to perform basic OS-specific I/O, like 00039 // testing for file existence and searching a 00040 // searchpath, as well as the best way to open an 00041 // fstream for reading or writing. 00042 //////////////////////////////////////////////////////////////////// 00043 class EXPCL_DTOOL Filename { 00044 PUBLISHED: 00045 enum Type { 00046 // These type values must fit within the bits allocated for 00047 // F_type, below. 00048 T_general = 0x00, 00049 T_dso = 0x01, 00050 T_executable = 0x02, 00051 // Perhaps other types will be added later. 00052 }; 00053 00054 public: 00055 enum Flags { 00056 F_type = 0x0f, 00057 F_binary = 0x10, 00058 F_text = 0x20, 00059 F_pattern = 0x40, 00060 }; 00061 00062 PUBLISHED: 00063 INLINE Filename(const string &filename = ""); 00064 INLINE Filename(const char *filename); 00065 INLINE Filename(const Filename ©); 00066 Filename(const Filename &dirname, const Filename &basename); 00067 INLINE ~Filename(); 00068 00069 #ifdef HAVE_PYTHON 00070 PyObject *__reduce__(PyObject *self) const; 00071 #endif 00072 00073 // Static constructors to explicitly create a filename that refers 00074 // to a text or binary file. This is in lieu of calling set_text() 00075 // or set_binary() or set_type(). 00076 INLINE static Filename text_filename(const string &filename); 00077 INLINE static Filename binary_filename(const string &filename); 00078 INLINE static Filename dso_filename(const string &filename); 00079 INLINE static Filename executable_filename(const string &filename); 00080 00081 INLINE static Filename pattern_filename(const string &filename); 00082 00083 static Filename from_os_specific(const string &os_specific, 00084 Type type = T_general); 00085 static Filename expand_from(const string &user_string, 00086 Type type = T_general); 00087 static Filename temporary(const string &dirname, const string &prefix, 00088 const string &suffix = string(), 00089 Type type = T_general); 00090 00091 static const Filename &get_home_directory(); 00092 static const Filename &get_temp_directory(); 00093 static const Filename &get_user_appdata_directory(); 00094 static const Filename &get_common_appdata_directory(); 00095 00096 // Assignment is via the = operator. 00097 INLINE Filename &operator = (const string &filename); 00098 INLINE Filename &operator = (const char *filename); 00099 INLINE Filename &operator = (const Filename ©); 00100 00101 // And retrieval is by any of the classic string operations. 00102 INLINE operator const string & () const; 00103 INLINE const char *c_str() const; 00104 INLINE bool empty() const; 00105 INLINE size_t length() const; 00106 INLINE char operator [] (int n) const; 00107 00108 INLINE string substr(size_t begin, size_t end = string::npos) const; 00109 INLINE void operator += (const string &other); 00110 INLINE Filename operator + (const string &other) const; 00111 00112 // Or, you can use any of these. 00113 INLINE string get_fullpath() const; 00114 INLINE string get_dirname() const; 00115 INLINE string get_basename() const; 00116 INLINE string get_fullpath_wo_extension() const; 00117 INLINE string get_basename_wo_extension() const; 00118 INLINE string get_extension() const; 00119 00120 // You can also use any of these to reassign pieces of the filename. 00121 void set_fullpath(const string &s); 00122 void set_dirname(const string &s); 00123 void set_basename(const string &s); 00124 void set_fullpath_wo_extension(const string &s); 00125 void set_basename_wo_extension(const string &s); 00126 void set_extension(const string &s); 00127 00128 // Setting these flags appropriately is helpful when opening or 00129 // searching for a file; it helps the Filename resolve OS-specific 00130 // conventions (for instance, that dynamic library names should 00131 // perhaps be changed from .so to .dll). 00132 INLINE void set_binary(); 00133 INLINE void set_text(); 00134 INLINE bool is_binary() const; 00135 INLINE bool is_text() const; 00136 00137 INLINE void set_type(Type type); 00138 INLINE Type get_type() const; 00139 00140 INLINE void set_pattern(bool pattern); 00141 INLINE bool get_pattern() const; 00142 00143 INLINE bool has_hash() const; 00144 Filename get_filename_index(int index) const; 00145 00146 INLINE string get_hash_to_end() const; 00147 void set_hash_to_end(const string &s); 00148 00149 void extract_components(vector_string &components) const; 00150 void standardize(); 00151 00152 // The following functions deal with the outside world. 00153 00154 INLINE bool is_local() const; 00155 INLINE bool is_fully_qualified() const; 00156 void make_absolute(); 00157 void make_absolute(const Filename &start_directory); 00158 00159 bool make_canonical(); 00160 bool make_true_case(); 00161 00162 string to_os_specific() const; 00163 string to_os_generic() const; 00164 string to_os_short_name() const; 00165 string to_os_long_name() const; 00166 00167 bool exists() const; 00168 bool is_regular_file() const; 00169 bool is_directory() const; 00170 bool is_executable() const; 00171 int compare_timestamps(const Filename &other, 00172 bool this_missing_is_old = true, 00173 bool other_missing_is_old = true) const; 00174 time_t get_timestamp() const; 00175 time_t get_access_timestamp() const; 00176 off_t get_file_size() const; 00177 00178 bool resolve_filename(const DSearchPath &searchpath, 00179 const string &default_extension = string()); 00180 bool make_relative_to(Filename directory, bool allow_backups = true); 00181 int find_on_searchpath(const DSearchPath &searchpath); 00182 00183 bool scan_directory(vector_string &contents) const; 00184 #ifdef HAVE_PYTHON 00185 PyObject *scan_directory() const; 00186 #endif 00187 00188 bool open_read(ifstream &stream) const; 00189 bool open_write(ofstream &stream, bool truncate = true) const; 00190 bool open_append(ofstream &stream) const; 00191 bool open_read_write(fstream &stream, bool truncate = false) const; 00192 bool open_read_append(fstream &stream) const; 00193 00194 #ifdef USE_PANDAFILESTREAM 00195 bool open_read(pifstream &stream) const; 00196 bool open_write(pofstream &stream, bool truncate = true) const; 00197 bool open_append(pofstream &stream) const; 00198 bool open_read_write(pfstream &stream, bool truncate = false) const; 00199 bool open_read_append(pfstream &stream) const; 00200 #endif // USE_PANDAFILESTREAM 00201 00202 bool chdir() const; 00203 bool touch() const; 00204 bool unlink() const; 00205 bool rename_to(const Filename &other) const; 00206 bool copy_to(const Filename &other) const; 00207 00208 bool make_dir() const; 00209 bool mkdir() const; 00210 bool rmdir() const; 00211 00212 // Comparison operators are handy. 00213 INLINE bool operator == (const string &other) const; 00214 INLINE bool operator != (const string &other) const; 00215 INLINE bool operator < (const string &other) const; 00216 INLINE int compare_to(const Filename &other) const; 00217 INLINE bool __nonzero__() const; 00218 int get_hash() const; 00219 00220 INLINE void output(ostream &out) const; 00221 00222 public: 00223 bool atomic_compare_and_exchange_contents(string &orig_contents, const string &old_contents, const string &new_contents) const; 00224 bool atomic_read_contents(string &contents) const; 00225 00226 protected: 00227 void locate_basename(); 00228 void locate_extension(); 00229 void locate_hash(); 00230 size_t get_common_prefix(const string &other) const; 00231 static int count_slashes(const string &str); 00232 bool r_make_canonical(const Filename &cwd); 00233 00234 string _filename; 00235 // We'll make these size_t instead of string::size_type to help out 00236 // cppParser. 00237 size_t _dirname_end; 00238 size_t _basename_start; 00239 size_t _basename_end; 00240 size_t _extension_start; 00241 size_t _hash_start; 00242 size_t _hash_end; 00243 00244 int _flags; 00245 00246 static Filename *_home_directory; 00247 static Filename *_temp_directory; 00248 static Filename *_user_appdata_directory; 00249 static Filename *_common_appdata_directory; 00250 00251 public: 00252 static TypeHandle get_class_type() { 00253 return _type_handle; 00254 } 00255 static void init_type() { 00256 register_type(_type_handle, "Filename"); 00257 } 00258 00259 private: 00260 static TypeHandle _type_handle; 00261 }; 00262 00263 INLINE ostream &operator << (ostream &out, const Filename &n) { 00264 n.output(out); 00265 return out; 00266 } 00267 00268 #include "filename.I" 00269 00270 #endif 00271 00272 00273