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