Panda3D
virtualFileMount.cxx
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 virtualFileMount.cxx
10  * @author drose
11  * @date 2002-08-03
12  */
13 
14 #include "virtualFileMount.h"
15 #include "virtualFileSimple.h"
16 #include "virtualFileSystem.h"
17 #include "zStream.h"
18 
19 using std::iostream;
20 using std::istream;
21 using std::ostream;
22 using std::string;
23 
24 TypeHandle VirtualFileMount::_type_handle;
25 
26 
27 /**
28  *
29  */
30 VirtualFileMount::
31 ~VirtualFileMount() {
32  nassertv(_file_system == nullptr);
33 }
34 
35 /**
36  * Constructs and returns a new VirtualFile instance that corresponds to the
37  * indicated filename within this mount point. The returned VirtualFile
38  * object does not imply that the given file actually exists; but if the file
39  * does exist, then the handle can be used to read it.
40  */
42 make_virtual_file(const Filename &local_filename,
43  const Filename &original_filename, bool implicit_pz_file,
44  int open_flags) {
45  Filename local(local_filename);
46  if (original_filename.is_text()) {
47  local.set_text();
48  } else {
49  local.set_binary();
50  }
51  PT(VirtualFileSimple) file =
52  new VirtualFileSimple(this, local, implicit_pz_file, open_flags);
53  file->set_original_filename(original_filename);
54 
55  if ((open_flags & VirtualFileSystem::OF_create_file) != 0) {
56  create_file(local);
57  } else if ((open_flags & VirtualFileSystem::OF_make_directory) != 0) {
58  make_directory(local);
59  }
60 
61  return file;
62 }
63 
64 /**
65  * Attempts to create the indicated file within the mount, if it does not
66  * already exist. Returns true on success (or if the file already exists), or
67  * false if it cannot be created.
68  */
70 create_file(const Filename &file) {
71  return false;
72 }
73 
74 /**
75  * Attempts to delete the indicated file or directory within the mount. This
76  * can remove a single file or an empty directory. It will not remove a
77  * nonempty directory. Returns true on success, false on failure.
78  */
80 delete_file(const Filename &file) {
81  return false;
82 }
83 
84 /**
85  * Attempts to rename the contents of the indicated file to the indicated
86  * file. Both filenames will be within the mount. Returns true on success,
87  * false on failure. If this returns false, this will be attempted again with
88  * a copy-and-delete operation.
89  */
91 rename_file(const Filename &orig_filename, const Filename &new_filename) {
92  return false;
93 }
94 
95 /**
96  * Attempts to copy the contents of the indicated file to the indicated file.
97  * Both filenames will be within the mount. Returns true on success, false on
98  * failure. If this returns false, the copy will be performed by explicit
99  * read-and-write operations.
100  */
102 copy_file(const Filename &orig_filename, const Filename &new_filename) {
103  return false;
104 }
105 
106 /**
107  * Attempts to create the indicated file within the mount, if it does not
108  * already exist. Returns true on success, or false if it cannot be created.
109  * If the directory already existed prior to this call, may return either true
110  * or false.
111  */
113 make_directory(const Filename &file) {
114  return false;
115 }
116 
117 /**
118  * Returns true if the named file or directory may be written to, false
119  * otherwise.
120  */
122 is_writable(const Filename &file) const {
123  return false;
124 }
125 
126 /**
127  * Fills up the indicated pvector with the contents of the file, if it is a
128  * regular file. Returns true on success, false otherwise.
129  */
131 read_file(const Filename &file, bool do_uncompress,
132  vector_uchar &result) const {
133  result.clear();
134 
135  istream *in = open_read_file(file, do_uncompress);
136  if (in == nullptr) {
137  express_cat.info()
138  << "Unable to read " << file << "\n";
139  return false;
140  }
141 
142  std::streamsize file_size = get_file_size(file, in);
143  if (file_size > 0) {
144  result.reserve((size_t)file_size);
145  }
146 
147  bool okflag = VirtualFile::simple_read_file(in, result);
148 
149  close_read_file(in);
150 
151  if (!okflag) {
152  express_cat.info()
153  << "Error while reading " << file << "\n";
154  }
155  return okflag;
156 }
157 
158 /**
159  * Writes the indicated data to the file, if it is a writable file. Returns
160  * true on success, false otherwise.
161  */
163 write_file(const Filename &file, bool do_compress,
164  const unsigned char *data, size_t data_size) {
165  ostream *out = open_write_file(file, do_compress, true);
166  if (out == nullptr) {
167  express_cat.info()
168  << "Unable to write " << file << "\n";
169  return false;
170  }
171 
172  out->write((const char *)data, data_size);
173  bool okflag = (!out->fail());
174  close_write_file(out);
175 
176  if (!okflag) {
177  express_cat.info()
178  << "Error while writing " << file << "\n";
179  }
180  return okflag;
181 }
182 
183 /**
184  * Opens the file for reading. Returns a newly allocated istream on success
185  * (which you should eventually delete when you are done reading). Returns
186  * NULL on failure.
187  *
188  * If do_uncompress is true, the file is also decompressed on-the-fly using
189  * zlib.
190  */
191 istream *VirtualFileMount::
192 open_read_file(const Filename &file, bool do_uncompress) const {
193  istream *result = open_read_file(file);
194 
195 #ifdef HAVE_ZLIB
196  if (result != nullptr && do_uncompress) {
197  // We have to slip in a layer to decompress the file on the fly.
198  IDecompressStream *wrapper = new IDecompressStream(result, true);
199  result = wrapper;
200  }
201 #endif // HAVE_ZLIB
202 
203  return result;
204 }
205 
206 /**
207  * Closes a file opened by a previous call to open_read_file(). This really
208  * just deletes the istream pointer, but it is recommended to use this
209  * interface instead of deleting it explicitly, to help work around compiler
210  * issues.
211  */
213 close_read_file(istream *stream) const {
215 }
216 
217 /**
218  * Opens the file for writing. Returns a newly allocated ostream on success
219  * (which you should eventually delete when you are done writing). Returns
220  * NULL on failure.
221  */
222 ostream *VirtualFileMount::
223 open_write_file(const Filename &file, bool truncate) {
224  return nullptr;
225 }
226 
227 /**
228  * Opens the file for writing. Returns a newly allocated ostream on success
229  * (which you should eventually delete when you are done writing). Returns
230  * NULL on failure.
231  *
232  * If do_compress is true, the file is also compressed on-the-fly using zlib.
233  */
234 ostream *VirtualFileMount::
235 open_write_file(const Filename &file, bool do_compress, bool truncate) {
236  ostream *result = open_write_file(file, truncate);
237 
238 #ifdef HAVE_ZLIB
239  if (result != nullptr && do_compress) {
240  // We have to slip in a layer to compress the file on the fly.
241  OCompressStream *wrapper = new OCompressStream(result, true);
242  result = wrapper;
243  }
244 #endif // HAVE_ZLIB
245 
246  return result;
247 }
248 
249 /**
250  * Works like open_write_file(), but the file is opened in append mode. Like
251  * open_write_file, the returned pointer should eventually be passed to
252  * close_write_file().
253  */
254 ostream *VirtualFileMount::
256  return nullptr;
257 }
258 
259 /**
260  * Closes a file opened by a previous call to open_write_file(). This really
261  * just deletes the ostream pointer, but it is recommended to use this
262  * interface instead of deleting it explicitly, to help work around compiler
263  * issues.
264  */
266 close_write_file(ostream *stream) {
268 }
269 
270 /**
271  * Opens the file for writing. Returns a newly allocated iostream on success
272  * (which you should eventually delete when you are done writing). Returns
273  * NULL on failure.
274  */
275 iostream *VirtualFileMount::
276 open_read_write_file(const Filename &file, bool truncate) {
277  return nullptr;
278 }
279 
280 /**
281  * Works like open_read_write_file(), but the file is opened in append mode.
282  * Like open_read_write_file, the returned pointer should eventually be passed
283  * to close_read_write_file().
284  */
285 iostream *VirtualFileMount::
287  return nullptr;
288 }
289 
290 /**
291  * Closes a file opened by a previous call to open_read_write_file(). This
292  * really just deletes the iostream pointer, but it is recommended to use this
293  * interface instead of deleting it explicitly, to help work around compiler
294  * issues.
295  */
297 close_read_write_file(iostream *stream) {
299 }
300 
301 /**
302  * Populates the SubfileInfo structure with the data representing where the
303  * file actually resides on disk, if this is knowable. Returns true if the
304  * file might reside on disk, and the info is populated, or false if it does
305  * not (or it is not known where the file resides), in which case the info is
306  * meaningless.
307  */
309 get_system_info(const Filename &file, SubfileInfo &info) {
310  return false;
311 }
312 
313 /**
314  * See Filename::atomic_compare_and_exchange_contents().
315  */
317 atomic_compare_and_exchange_contents(const Filename &file, string &orig_contents,
318  const string &old_contents,
319  const string &new_contents) {
320  return false;
321 }
322 
323 /**
324  * See Filename::atomic_read_contents().
325  */
327 atomic_read_contents(const Filename &file, string &contents) const {
328  return false;
329 }
330 
331 /**
332  *
333  */
334 void VirtualFileMount::
335 output(ostream &out) const {
336  out << get_type();
337 }
338 
339 /**
340  *
341  */
342 void VirtualFileMount::
343 write(ostream &out) const {
344  out << *this << " on /" << get_mount_point() << "\n";
345 }
virtual void close_write_file(std::ostream *stream)
Closes a file opened by a previous call to open_write_file().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void close_read_write_file(std::iostream *stream)
Closes a file opened by a previous call to open_read_write_file().
virtual void close_read_file(std::istream *stream) const
Closes a file opened by a previous call to open_read_file().
virtual bool atomic_read_contents(const Filename &file, std::string &contents) const
See Filename::atomic_read_contents().
const Filename & get_mount_point() const
Returns the name of the directory within the virtual file system that this mount object is attached t...
void set_binary()
Indicates that the filename represents a binary file.
Definition: filename.I:414
void set_text()
Indicates that the filename represents a text file.
Definition: filename.I:424
virtual bool delete_file(const Filename &file)
Attempts to delete the indicated file or directory within the mount.
virtual void close_read_write_file(std::iostream *stream)
Closes a file opened by a previous call to open_read_write_file().
The abstract base class for a file or directory within the VirtualFileSystem.
Definition: virtualFile.h:35
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool copy_file(const Filename &orig_filename, const Filename &new_filename)
Attempts to copy the contents of the indicated file to the indicated file.
virtual bool rename_file(const Filename &orig_filename, const Filename &new_filename)
Attempts to rename the contents of the indicated file to the indicated file.
virtual bool is_writable(const Filename &file) const
Returns true if the named file or directory may be written to, false otherwise.
static void close_read_file(std::istream *stream)
Closes a file opened by a previous call to open_read_file().
virtual bool create_file(const Filename &file)
Attempts to create the indicated file within the mount, if it does not already exist.
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
virtual bool atomic_compare_and_exchange_contents(const Filename &file, std::string &orig_contents, const std::string &old_contents, const std::string &new_contents)
See Filename::atomic_compare_and_exchange_contents().
virtual bool write_file(const Filename &file, bool do_compress, const unsigned char *data, size_t data_size)
Writes the indicated data to the file, if it is a writable file.
virtual std::ostream * open_append_file(const Filename &file)
Works like open_write_file(), but the file is opened in append mode.
virtual std::iostream * open_read_append_file(const Filename &file)
Works like open_read_write_file(), but the file is opened in append mode.
bool is_text() const
Returns true if the Filename has been indicated to represent a text file via a previous call to set_t...
Definition: filename.I:456
virtual bool make_directory(const Filename &file)
Attempts to create the indicated file within the mount, if it does not already exist.
static void close_write_file(std::ostream *stream)
Closes a file opened by a previous call to open_write_file().
virtual bool get_system_info(const Filename &file, SubfileInfo &info)
Populates the SubfileInfo structure with the data representing where the file actually resides on dis...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class records a particular byte sub-range within an existing file on disk.
Definition: subfileInfo.h:26
static bool simple_read_file(std::istream *stream, vector_uchar &result)
Fills up the indicated pvector with the contents of the just-opened file.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
A simple file or directory within the VirtualFileSystem: this maps to exactly one file on one mount p...
virtual bool read_file(const Filename &file, bool do_uncompress, vector_uchar &result) const
Fills up the indicated pvector with the contents of the file, if it is a regular file.
virtual std::ostream * open_write_file(const Filename &file, bool truncate)
Opens the file for writing.
virtual PointerTo< VirtualFile > make_virtual_file(const Filename &local_filename, const Filename &original_filename, bool implicit_pz_file, int open_flags)
Constructs and returns a new VirtualFile instance that corresponds to the indicated filename within t...
virtual std::iostream * open_read_write_file(const Filename &file, bool truncate)
Opens the file for writing.