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