Panda3D

filename.h

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 &copy);
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 &copy);
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 
 All Classes Functions Variables Enumerations