Panda3D
filename.h
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file filename.h
10  * @author drose
11  * @date 1999-01-18
12  */
13 
14 #ifndef FILENAME_H
15 #define FILENAME_H
16 
17 #include "dtoolbase.h"
18 #include "pandaFileStream.h"
19 #include "typeHandle.h"
20 #include "register_type.h"
21 #include "vector_string.h"
22 #include "textEncoder.h"
23 
24 #include <assert.h>
25 
26 class DSearchPath;
27 
28 /**
29  * The name of a file, such as a texture file or an Egg file. Stores the full
30  * pathname, and includes functions for extracting out the directory prefix
31  * part and the file extension and stuff.
32  *
33  * A Filename is also aware of the mapping between the Unix-like filename
34  * convention we use internally, and the local OS's specific filename
35  * convention, and it knows how to perform basic OS-specific I/O, like testing
36  * for file existence and searching a searchpath, as well as the best way to
37  * open an fstream for reading or writing.
38  */
39 class EXPCL_DTOOL_DTOOLUTIL Filename {
40 PUBLISHED:
41  enum Type {
42  // These type values must fit within the bits allocated for F_type, below.
43  T_general = 0x00,
44  T_dso = 0x01,
45  T_executable = 0x02,
46  // Perhaps other types will be added later.
47  };
48 
49 public:
50  enum Flags {
51  F_type = 0x0f,
52  F_binary = 0x10,
53  F_text = 0x20,
54  F_pattern = 0x40,
55  };
56 
57  INLINE Filename(const char *filename);
58  INLINE Filename(const std::string &filename);
59  INLINE Filename(const std::wstring &filename);
60  INLINE Filename(const Filename &copy);
61  INLINE Filename(std::string &&filename) noexcept;
62  INLINE Filename(Filename &&from) noexcept;
63 
64 PUBLISHED:
65  INLINE Filename();
66  Filename(const Filename &dirname, const Filename &basename);
67 
68 #ifdef HAVE_PYTHON
69  EXTENSION(Filename(PyObject *path));
70 
71  EXTENSION(PyObject *__reduce__(PyObject *self) const);
72 #endif
73 
74  // Static constructors to explicitly create a filename that refers to a text
75  // or binary file. This is in lieu of calling set_text() or set_binary() or
76  // set_type().
77  INLINE static Filename text_filename(const Filename &filename);
78  INLINE static Filename text_filename(const std::string &filename);
79  INLINE static Filename binary_filename(const Filename &filename);
80  INLINE static Filename binary_filename(const std::string &filename);
81  INLINE static Filename dso_filename(const std::string &filename);
82  INLINE static Filename executable_filename(const std::string &filename);
83 
84  INLINE static Filename pattern_filename(const std::string &filename);
85 
86  static Filename from_os_specific(const std::string &os_specific,
87  Type type = T_general);
88  static Filename from_os_specific_w(const std::wstring &os_specific,
89  Type type = T_general);
90  static Filename expand_from(const std::string &user_string,
91  Type type = T_general);
92  static Filename temporary(const std::string &dirname, const std::string &prefix,
93  const std::string &suffix = std::string(),
94  Type type = T_general);
95 
96  static const Filename &get_home_directory();
97  static const Filename &get_temp_directory();
98  static const Filename &get_user_appdata_directory();
99  static const Filename &get_common_appdata_directory();
100 
101  // Assignment is via the = operator.
102  INLINE Filename &operator = (const std::string &filename);
103  INLINE Filename &operator = (const std::wstring &filename);
104  INLINE Filename &operator = (const char *filename);
105  INLINE Filename &operator = (const Filename &copy);
106  INLINE Filename &operator = (std::string &&filename) noexcept;
107  INLINE Filename &operator = (Filename &&from) noexcept;
108 
109  // And retrieval is by any of the classic string operations.
110  INLINE operator const std::string & () const;
111  INLINE const char *c_str() const;
112  INLINE bool empty() const;
113  INLINE size_t length() const;
114  INLINE char operator [] (size_t n) const;
115 
116  EXTENSION(PyObject *__repr__() const);
117  EXTENSION(PyObject *__fspath__() const);
118 
119  INLINE std::string substr(size_t begin) const;
120  INLINE std::string substr(size_t begin, size_t end) const;
121  INLINE void operator += (const std::string &other);
122  INLINE Filename operator + (const std::string &other) const;
123 
124  INLINE Filename operator / (const Filename &other) const;
125 
126  // Or, you can use any of these.
127  INLINE std::string get_fullpath() const;
128  INLINE std::wstring get_fullpath_w() const;
129  INLINE std::string get_dirname() const;
130  INLINE std::string get_basename() const;
131  INLINE std::string get_fullpath_wo_extension() const;
132  INLINE std::string get_basename_wo_extension() const;
133  INLINE std::string get_extension() const;
134 
135  // You can also use any of these to reassign pieces of the filename.
136  void set_fullpath(const std::string &s);
137  void set_dirname(const std::string &s);
138  void set_basename(const std::string &s);
139  void set_fullpath_wo_extension(const std::string &s);
140  void set_basename_wo_extension(const std::string &s);
141  void set_extension(const std::string &s);
142 
143  // Setting these flags appropriately is helpful when opening or searching
144  // for a file; it helps the Filename resolve OS-specific conventions (for
145  // instance, that dynamic library names should perhaps be changed from .so
146  // to .dll).
147  INLINE void set_binary();
148  INLINE void set_text();
149  INLINE bool is_binary() const;
150  INLINE bool is_text() const;
151  INLINE bool is_binary_or_text() const;
152 
153  INLINE void set_type(Type type);
154  INLINE Type get_type() const;
155 
156  INLINE void set_pattern(bool pattern);
157  INLINE bool get_pattern() const;
158 
159  INLINE bool has_hash() const;
160  Filename get_filename_index(int index) const;
161 
162  INLINE std::string get_hash_to_end() const;
163  void set_hash_to_end(const std::string &s);
164 
165  void extract_components(vector_string &components) const;
166  void standardize();
167 
168  // The following functions deal with the outside world.
169 
170  INLINE bool is_local() const;
171  INLINE bool is_fully_qualified() const;
172  void make_absolute();
173  void make_absolute(const Filename &start_directory);
174 
175  bool make_canonical();
176  bool make_true_case();
177 
178  std::string to_os_specific() const;
179  std::wstring to_os_specific_w() const;
180  std::string to_os_generic() const;
181  std::string to_os_short_name() const;
182  std::string to_os_long_name() const;
183 
184  bool exists() const;
185  bool is_regular_file() const;
186  bool is_writable() const;
187  bool is_directory() const;
188  bool is_executable() const;
189  int compare_timestamps(const Filename &other,
190  bool this_missing_is_old = true,
191  bool other_missing_is_old = true) const;
192  time_t get_timestamp() const;
193  time_t get_access_timestamp() const;
194  std::streamsize get_file_size() const;
195 
196  bool resolve_filename(const DSearchPath &searchpath,
197  const std::string &default_extension = std::string());
198  bool make_relative_to(Filename directory, bool allow_backups = true);
199  int find_on_searchpath(const DSearchPath &searchpath);
200 
201  bool scan_directory(vector_string &contents) const;
202 #ifdef HAVE_PYTHON
203  EXTENSION(PyObject *scan_directory() const);
204 #endif
205 
206  bool open_read(std::ifstream &stream) const;
207  bool open_write(std::ofstream &stream, bool truncate = true) const;
208  bool open_append(std::ofstream &stream) const;
209  bool open_read_write(std::fstream &stream, bool truncate = false) const;
210  bool open_read_append(std::fstream &stream) const;
211 
212 #ifdef USE_PANDAFILESTREAM
213  bool open_read(pifstream &stream) const;
214  bool open_write(pofstream &stream, bool truncate = true) const;
215  bool open_append(pofstream &stream) const;
216  bool open_read_write(pfstream &stream, bool truncate = false) const;
217  bool open_read_append(pfstream &stream) const;
218 #endif // USE_PANDAFILESTREAM
219 
220  bool chdir() const;
221  bool touch() const;
222  bool unlink() const;
223  BLOCKING bool rename_to(const Filename &other) const;
224  BLOCKING bool copy_to(const Filename &other) const;
225 
226  bool make_dir() const;
227  bool mkdir() const;
228  bool rmdir() const;
229 
230  // Comparison operators are handy.
231  INLINE bool operator == (const std::string &other) const;
232  INLINE bool operator != (const std::string &other) const;
233  INLINE bool operator < (const std::string &other) const;
234  INLINE int compare_to(const Filename &other) const;
235  INLINE bool __nonzero__() const;
236  int get_hash() const;
237 
238  INLINE void output(std::ostream &out) const;
239 
240  INLINE static void set_filesystem_encoding(TextEncoder::Encoding encoding);
241  INLINE static TextEncoder::Encoding get_filesystem_encoding();
242 
243 public:
244  bool atomic_compare_and_exchange_contents(std::string &orig_contents, const std::string &old_contents, const std::string &new_contents) const;
245  bool atomic_read_contents(std::string &contents) const;
246 
247 protected:
248  void locate_basename();
249  void locate_extension();
250  void locate_hash();
251  size_t get_common_prefix(const std::string &other) const;
252  static int count_slashes(const std::string &str);
253  bool r_make_canonical(const Filename &cwd);
254 
255  std::string _filename;
256  // We'll make these size_t instead of string::size_type to help out
257  // cppParser.
258  size_t _dirname_end;
259  size_t _basename_start;
260  size_t _basename_end;
261  size_t _extension_start;
262  size_t _hash_start;
263  size_t _hash_end;
264 
265  int _flags;
266 
267  static TextEncoder::Encoding _filesystem_encoding;
268  static TVOLATILE AtomicAdjust::Pointer _home_directory;
269  static TVOLATILE AtomicAdjust::Pointer _temp_directory;
270  static TVOLATILE AtomicAdjust::Pointer _user_appdata_directory;
271  static TVOLATILE AtomicAdjust::Pointer _common_appdata_directory;
272 
273 #ifdef ANDROID
274 public:
275  static std::string _internal_data_dir;
276 #endif
277 
278 public:
279  static TypeHandle get_class_type() {
280  return _type_handle;
281  }
282  static void init_type() {
283  register_type(_type_handle, "Filename");
284  }
285 
286 private:
287  static TypeHandle _type_handle;
288 };
289 
290 INLINE std::ostream &operator << (std::ostream &out, const Filename &n) {
291  n.output(out);
292  return out;
293 }
294 
295 #include "filename.I"
296 
297 #endif
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void register_type(TypeHandle &type_handle, const std::string &name)
This inline function is just a convenient way to call TypeRegistry::register_type(),...
Definition: register_type.I:22
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An STL function object class, this is intended to be used on any ordered collection of class objects ...
Definition: stl_compares.h:73
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class stores a list of directories that can be searched, in order, to locate a particular file.
Definition: dSearchPath.h:28
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.