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  EXTENSION(Filename __truediv__(const Filename &other) const);
126 
127  // Or, you can use any of these.
128  INLINE std::string get_fullpath() const;
129  INLINE std::wstring get_fullpath_w() const;
130  INLINE std::string get_dirname() const;
131  INLINE std::string get_basename() const;
132  INLINE std::string get_fullpath_wo_extension() const;
133  INLINE std::string get_basename_wo_extension() const;
134  INLINE std::string get_extension() const;
135 
136  // You can also use any of these to reassign pieces of the filename.
137  void set_fullpath(const std::string &s);
138  void set_dirname(const std::string &s);
139  void set_basename(const std::string &s);
140  void set_fullpath_wo_extension(const std::string &s);
141  void set_basename_wo_extension(const std::string &s);
142  void set_extension(const std::string &s);
143 
144  // Setting these flags appropriately is helpful when opening or searching
145  // for a file; it helps the Filename resolve OS-specific conventions (for
146  // instance, that dynamic library names should perhaps be changed from .so
147  // to .dll).
148  INLINE void set_binary();
149  INLINE void set_text();
150  INLINE bool is_binary() const;
151  INLINE bool is_text() const;
152  INLINE bool is_binary_or_text() const;
153 
154  INLINE void set_type(Type type);
155  INLINE Type get_type() const;
156 
157  INLINE void set_pattern(bool pattern);
158  INLINE bool get_pattern() const;
159 
160  INLINE bool has_hash() const;
161  Filename get_filename_index(int index) const;
162 
163  INLINE std::string get_hash_to_end() const;
164  void set_hash_to_end(const std::string &s);
165 
166  void extract_components(vector_string &components) const;
167  void standardize();
168 
169  // The following functions deal with the outside world.
170 
171  INLINE bool is_local() const;
172  INLINE bool is_fully_qualified() const;
173  void make_absolute();
174  void make_absolute(const Filename &start_directory);
175 
176  bool make_canonical();
177  bool make_true_case();
178 
179  std::string to_os_specific() const;
180  std::wstring to_os_specific_w() const;
181  std::string to_os_generic() const;
182  std::string to_os_short_name() const;
183  std::string to_os_long_name() const;
184 
185  bool exists() const;
186  bool is_regular_file() const;
187  bool is_writable() const;
188  bool is_directory() const;
189  bool is_executable() const;
190  int compare_timestamps(const Filename &other,
191  bool this_missing_is_old = true,
192  bool other_missing_is_old = true) const;
193  time_t get_timestamp() const;
194  time_t get_access_timestamp() const;
195  std::streamsize get_file_size() const;
196 
197  bool resolve_filename(const DSearchPath &searchpath,
198  const std::string &default_extension = std::string());
199  bool make_relative_to(Filename directory, bool allow_backups = true);
200  int find_on_searchpath(const DSearchPath &searchpath);
201 
202  bool scan_directory(vector_string &contents) const;
203 #ifdef HAVE_PYTHON
204  EXTENSION(PyObject *scan_directory() const);
205 #endif
206 
207  bool open_read(std::ifstream &stream) const;
208  bool open_write(std::ofstream &stream, bool truncate = true) const;
209  bool open_append(std::ofstream &stream) const;
210  bool open_read_write(std::fstream &stream, bool truncate = false) const;
211  bool open_read_append(std::fstream &stream) const;
212 
213 #ifdef USE_PANDAFILESTREAM
214  bool open_read(pifstream &stream) const;
215  bool open_write(pofstream &stream, bool truncate = true) const;
216  bool open_append(pofstream &stream) const;
217  bool open_read_write(pfstream &stream, bool truncate = false) const;
218  bool open_read_append(pfstream &stream) const;
219 #endif // USE_PANDAFILESTREAM
220 
221  bool chdir() const;
222  bool touch() const;
223  bool unlink() const;
224  BLOCKING bool rename_to(const Filename &other) const;
225  BLOCKING bool copy_to(const Filename &other) const;
226 
227  bool make_dir() const;
228  bool mkdir() const;
229  bool rmdir() const;
230 
231  // Comparison operators are handy.
232  INLINE bool operator == (const std::string &other) const;
233  INLINE bool operator != (const std::string &other) const;
234  INLINE bool operator < (const std::string &other) const;
235  INLINE int compare_to(const Filename &other) const;
236  INLINE bool __nonzero__() const;
237  int get_hash() const;
238 
239  INLINE void output(std::ostream &out) const;
240 
241  INLINE static void set_filesystem_encoding(TextEncoder::Encoding encoding);
242  INLINE static TextEncoder::Encoding get_filesystem_encoding();
243 
244 public:
245  bool atomic_compare_and_exchange_contents(std::string &orig_contents, const std::string &old_contents, const std::string &new_contents) const;
246  bool atomic_read_contents(std::string &contents) const;
247 
248 protected:
249  void locate_basename();
250  void locate_extension();
251  void locate_hash();
252  size_t get_common_prefix(const std::string &other) const;
253  static int count_slashes(const std::string &str);
254  bool r_make_canonical(const Filename &cwd);
255 
256  std::string _filename;
257  // We'll make these size_t instead of string::size_type to help out
258  // cppParser.
259  size_t _dirname_end;
260  size_t _basename_start;
261  size_t _basename_end;
262  size_t _extension_start;
263  size_t _hash_start;
264  size_t _hash_end;
265 
266  int _flags;
267 
268  static TextEncoder::Encoding _filesystem_encoding;
269  static TVOLATILE AtomicAdjust::Pointer _home_directory;
270  static TVOLATILE AtomicAdjust::Pointer _temp_directory;
271  static TVOLATILE AtomicAdjust::Pointer _user_appdata_directory;
272  static TVOLATILE AtomicAdjust::Pointer _common_appdata_directory;
273 
274 #ifdef ANDROID
275 public:
276  static std::string _internal_data_dir;
277 #endif
278 
279 public:
280  static TypeHandle get_class_type() {
281  return _type_handle;
282  }
283  static void init_type() {
284  register_type(_type_handle, "Filename");
285  }
286 
287 private:
288  static TypeHandle _type_handle;
289 };
290 
291 INLINE std::ostream &operator << (std::ostream &out, const Filename &n) {
292  n.output(out);
293  return out;
294 }
295 
296 #include "filename.I"
297 
298 #endif
This class stores a list of directories that can be searched, in order, to locate a particular file.
Definition: dSearchPath.h:28
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.