Panda3D
virtualFileMount.cxx
1 // Filename: virtualFileMount.cxx
2 // Created by: drose (03Aug02)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "virtualFileMount.h"
16 #include "virtualFileSimple.h"
17 #include "virtualFileSystem.h"
18 #include "zStream.h"
19 
20 TypeHandle VirtualFileMount::_type_handle;
21 
22 
23 ////////////////////////////////////////////////////////////////////
24 // Function: VirtualFileMount::Destructor
25 // Access: Public, Virtual
26 // Description:
27 ////////////////////////////////////////////////////////////////////
28 VirtualFileMount::
29 ~VirtualFileMount() {
30  nassertv(_file_system == NULL);
31 }
32 
33 ////////////////////////////////////////////////////////////////////
34 // Function: VirtualFileMount::make_virtual_file
35 // Access: Public, Virtual
36 // Description: Constructs and returns a new VirtualFile instance
37 // that corresponds to the indicated filename within
38 // this mount point. The returned VirtualFile object
39 // does not imply that the given file actually exists;
40 // but if the file does exist, then the handle can be
41 // used to read it.
42 ////////////////////////////////////////////////////////////////////
44 make_virtual_file(const Filename &local_filename,
45  const Filename &original_filename, bool implicit_pz_file,
46  int open_flags) {
47  Filename local(local_filename);
48  if (original_filename.is_text()) {
49  local.set_text();
50  } else {
51  local.set_binary();
52  }
53  PT(VirtualFileSimple) file =
54  new VirtualFileSimple(this, local, implicit_pz_file, open_flags);
55  file->set_original_filename(original_filename);
56 
57  if ((open_flags & VirtualFileSystem::OF_create_file) != 0) {
58  create_file(local);
59  } else if ((open_flags & VirtualFileSystem::OF_make_directory) != 0) {
60  make_directory(local);
61  }
62 
63  return file.p();
64 }
65 
66 ////////////////////////////////////////////////////////////////////
67 // Function: VirtualFileMount::create_file
68 // Access: Public, Virtual
69 // Description: Attempts to create the indicated file within the
70 // mount, if it does not already exist. Returns true on
71 // success (or if the file already exists), or false if
72 // it cannot be created.
73 ////////////////////////////////////////////////////////////////////
75 create_file(const Filename &file) {
76  return false;
77 }
78 
79 ////////////////////////////////////////////////////////////////////
80 // Function: VirtualFileMount::delete_file
81 // Access: Public, Virtual
82 // Description: Attempts to delete the indicated file or directory
83 // within the mount. This can remove a single file or
84 // an empty directory. It will not remove a nonempty
85 // directory. Returns true on success, false on
86 // failure.
87 ////////////////////////////////////////////////////////////////////
89 delete_file(const Filename &file) {
90  return false;
91 }
92 
93 ////////////////////////////////////////////////////////////////////
94 // Function: VirtualFileMount::rename_file
95 // Access: Public
96 // Description: Attempts to rename the contents of the indicated file
97 // to the indicated file. Both filenames will be within
98 // the mount. Returns true on success, false on
99 // failure. If this returns false, this will be
100 // attempted again with a copy-and-delete operation.
101 ////////////////////////////////////////////////////////////////////
103 rename_file(const Filename &orig_filename, const Filename &new_filename) {
104  return false;
105 }
106 
107 ////////////////////////////////////////////////////////////////////
108 // Function: VirtualFileMount::copy_file
109 // Access: Public
110 // Description: Attempts to copy the contents of the indicated file
111 // to the indicated file. Both filenames will be within
112 // the mount. Returns true on success, false on
113 // failure. If this returns false, the copy will be
114 // performed by explicit read-and-write operations.
115 ////////////////////////////////////////////////////////////////////
117 copy_file(const Filename &orig_filename, const Filename &new_filename) {
118  return false;
119 }
120 
121 ////////////////////////////////////////////////////////////////////
122 // Function: VirtualFileMount::make_directory
123 // Access: Public, Virtual
124 // Description: Attempts to create the indicated file within the
125 // mount, if it does not already exist. Returns true on
126 // success, or false if it cannot be created. If the
127 // directory already existed prior to this call, may
128 // return either true or false.
129 ////////////////////////////////////////////////////////////////////
131 make_directory(const Filename &file) {
132  return false;
133 }
134 
135 ////////////////////////////////////////////////////////////////////
136 // Function: VirtualFileMount::is_writable
137 // Access: Public, Virtual
138 // Description: Returns true if the named file or directory may be
139 // written to, false otherwise.
140 ////////////////////////////////////////////////////////////////////
142 is_writable(const Filename &file) const {
143  return false;
144 }
145 
146 ////////////////////////////////////////////////////////////////////
147 // Function: VirtualFileMount::read_file
148 // Access: Public, Virtual
149 // Description: Fills up the indicated pvector with the contents of
150 // the file, if it is a regular file. Returns true on
151 // success, false otherwise.
152 ////////////////////////////////////////////////////////////////////
154 read_file(const Filename &file, bool do_uncompress,
155  pvector<unsigned char> &result) const {
156  result.clear();
157 
158  istream *in = open_read_file(file, do_uncompress);
159  if (in == (istream *)NULL) {
160  express_cat.info()
161  << "Unable to read " << file << "\n";
162  return false;
163  }
164 
165  streamsize file_size = get_file_size(file, in);
166  if (file_size > 0) {
167  result.reserve((size_t)file_size);
168  }
169 
170  bool okflag = VirtualFile::simple_read_file(in, result);
171 
172  close_read_file(in);
173 
174  if (!okflag) {
175  express_cat.info()
176  << "Error while reading " << file << "\n";
177  }
178  return okflag;
179 }
180 
181 ////////////////////////////////////////////////////////////////////
182 // Function: VirtualFileMount::write_file
183 // Access: Public, Virtual
184 // Description: Writes the indicated data to the file, if it is a
185 // writable file. Returns true on success, false
186 // otherwise.
187 ////////////////////////////////////////////////////////////////////
189 write_file(const Filename &file, bool do_compress,
190  const unsigned char *data, size_t data_size) {
191  ostream *out = open_write_file(file, do_compress, true);
192  if (out == (ostream *)NULL) {
193  express_cat.info()
194  << "Unable to write " << file << "\n";
195  return false;
196  }
197 
198  out->write((const char *)data, data_size);
199  bool okflag = (!out->fail());
200  close_write_file(out);
201 
202  if (!okflag) {
203  express_cat.info()
204  << "Error while writing " << file << "\n";
205  }
206  return okflag;
207 }
208 
209 ////////////////////////////////////////////////////////////////////
210 // Function: VirtualFileMount::open_read_file
211 // Access: Published, Virtual
212 // Description: Opens the file for reading. Returns a newly
213 // allocated istream on success (which you should
214 // eventually delete when you are done reading).
215 // Returns NULL on failure.
216 //
217 // If do_uncompress is true, the file is also
218 // decompressed on-the-fly using zlib.
219 ////////////////////////////////////////////////////////////////////
220 istream *VirtualFileMount::
221 open_read_file(const Filename &file, bool do_uncompress) const {
222  istream *result = open_read_file(file);
223 
224 #ifdef HAVE_ZLIB
225  if (result != (istream *)NULL && do_uncompress) {
226  // We have to slip in a layer to decompress the file on the fly.
227  IDecompressStream *wrapper = new IDecompressStream(result, true);
228  result = wrapper;
229  }
230 #endif // HAVE_ZLIB
231 
232  return result;
233 }
234 
235 ////////////////////////////////////////////////////////////////////
236 // Function: VirtualFileMount::close_read_file
237 // Access: Public, Virtual
238 // Description: Closes a file opened by a previous call to
239 // open_read_file(). This really just deletes the
240 // istream pointer, but it is recommended to use this
241 // interface instead of deleting it explicitly, to help
242 // work around compiler issues.
243 ////////////////////////////////////////////////////////////////////
245 close_read_file(istream *stream) const {
247 }
248 
249 ////////////////////////////////////////////////////////////////////
250 // Function: VirtualFileMount::open_write_file
251 // Access: Published, Virtual
252 // Description: Opens the file for writing. Returns a newly
253 // allocated ostream on success (which you should
254 // eventually delete when you are done writing).
255 // Returns NULL on failure.
256 ////////////////////////////////////////////////////////////////////
257 ostream *VirtualFileMount::
258 open_write_file(const Filename &file, bool truncate) {
259  return NULL;
260 }
261 
262 ////////////////////////////////////////////////////////////////////
263 // Function: VirtualFileMount::open_write_file
264 // Access: Published
265 // Description: Opens the file for writing. Returns a newly
266 // allocated ostream on success (which you should
267 // eventually delete when you are done writing).
268 // Returns NULL on failure.
269 //
270 // If do_compress is true, the file is also
271 // compressed on-the-fly using zlib.
272 ////////////////////////////////////////////////////////////////////
273 ostream *VirtualFileMount::
274 open_write_file(const Filename &file, bool do_compress, bool truncate) {
275  ostream *result = open_write_file(file, truncate);
276 
277 #ifdef HAVE_ZLIB
278  if (result != (ostream *)NULL && do_compress) {
279  // We have to slip in a layer to compress the file on the fly.
280  OCompressStream *wrapper = new OCompressStream(result, true);
281  result = wrapper;
282  }
283 #endif // HAVE_ZLIB
284 
285  return result;
286 }
287 
288 ////////////////////////////////////////////////////////////////////
289 // Function: VirtualFileMount::open_append_file
290 // Access: Published, Virtual
291 // Description: Works like open_write_file(), but the file is opened
292 // in append mode. Like open_write_file, the returned
293 // pointer should eventually be passed to
294 // close_write_file().
295 ////////////////////////////////////////////////////////////////////
296 ostream *VirtualFileMount::
298  return NULL;
299 }
300 
301 ////////////////////////////////////////////////////////////////////
302 // Function: VirtualFileMount::close_write_file
303 // Access: Public, Virtual
304 // Description: Closes a file opened by a previous call to
305 // open_write_file(). This really just deletes the
306 // ostream pointer, but it is recommended to use this
307 // interface instead of deleting it explicitly, to help
308 // work around compiler issues.
309 ////////////////////////////////////////////////////////////////////
311 close_write_file(ostream *stream) {
313 }
314 
315 ////////////////////////////////////////////////////////////////////
316 // Function: VirtualFileMount::open_read_write_file
317 // Access: Published, Virtual
318 // Description: Opens the file for writing. Returns a newly
319 // allocated iostream on success (which you should
320 // eventually delete when you are done writing).
321 // Returns NULL on failure.
322 ////////////////////////////////////////////////////////////////////
323 iostream *VirtualFileMount::
324 open_read_write_file(const Filename &file, bool truncate) {
325  return NULL;
326 }
327 
328 ////////////////////////////////////////////////////////////////////
329 // Function: VirtualFileMount::open_read_append_file
330 // Access: Published, Virtual
331 // Description: Works like open_read_write_file(), but the file is opened
332 // in append mode. Like open_read_write_file, the returned
333 // pointer should eventually be passed to
334 // close_read_write_file().
335 ////////////////////////////////////////////////////////////////////
336 iostream *VirtualFileMount::
338  return NULL;
339 }
340 
341 ////////////////////////////////////////////////////////////////////
342 // Function: VirtualFileMount::close_read_write_file
343 // Access: Public, Virtual
344 // Description: Closes a file opened by a previous call to
345 // open_read_write_file(). This really just deletes the
346 // iostream pointer, but it is recommended to use this
347 // interface instead of deleting it explicitly, to help
348 // work around compiler issues.
349 ////////////////////////////////////////////////////////////////////
351 close_read_write_file(iostream *stream) {
353 }
354 
355 ////////////////////////////////////////////////////////////////////
356 // Function: VirtualFileMount::get_system_info
357 // Access: Public, Virtual
358 // Description: Populates the SubfileInfo structure with the data
359 // representing where the file actually resides on disk,
360 // if this is knowable. Returns true if the file might
361 // reside on disk, and the info is populated, or false
362 // if it does not (or it is not known where the file
363 // resides), in which case the info is meaningless.
364 ////////////////////////////////////////////////////////////////////
366 get_system_info(const Filename &file, SubfileInfo &info) {
367  return false;
368 }
369 
370 ////////////////////////////////////////////////////////////////////
371 // Function: VirtualFileMount::atomic_compare_and_exchange_contents
372 // Access: Public, Virtual
373 // Description: See Filename::atomic_compare_and_exchange_contents().
374 ////////////////////////////////////////////////////////////////////
376 atomic_compare_and_exchange_contents(const Filename &file, string &orig_contents,
377  const string &old_contents,
378  const string &new_contents) {
379  return false;
380 }
381 
382 ////////////////////////////////////////////////////////////////////
383 // Function: VirtualFileMount::atomic_read_contents
384 // Access: Public, Virtual
385 // Description: See Filename::atomic_read_contents().
386 ////////////////////////////////////////////////////////////////////
388 atomic_read_contents(const Filename &file, string &contents) const {
389  return false;
390 }
391 
392 ////////////////////////////////////////////////////////////////////
393 // Function: VirtualFileMount::output
394 // Access: Public, Virtual
395 // Description:
396 ////////////////////////////////////////////////////////////////////
397 void VirtualFileMount::
398 output(ostream &out) const {
399  out << get_type();
400 }
401 
402 ////////////////////////////////////////////////////////////////////
403 // Function: VirtualFileMount::write
404 // Access: Public, Virtual
405 // Description:
406 ////////////////////////////////////////////////////////////////////
407 void VirtualFileMount::
408 write(ostream &out) const {
409  out << *this << " on /" << get_mount_point() << "\n";
410 }
virtual void close_read_file(istream *stream) const
Closes a file opened by a previous call to open_read_file().
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:494
virtual bool read_file(const Filename &file, bool do_uncompress, pvector< unsigned char > &result) const
Fills up the indicated pvector with the contents of the file, if it is a regular file.
void set_text()
Indicates that the filename represents a text file.
Definition: filename.I:507
virtual bool delete_file(const Filename &file)
Attempts to delete the indicated file or directory within the mount.
virtual bool atomic_read_contents(const Filename &file, string &contents) const
See Filename::atomic_read_contents().
static void close_read_write_file(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:37
static void close_read_file(istream *stream)
Closes a file opened by a previous call to open_read_file().
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.
virtual bool create_file(const Filename &file)
Attempts to create the indicated file within the mount, if it does not already exist.
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:44
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 ostream * open_append_file(const Filename &file)
Works like open_write_file(), but the file is opened in append mode.
virtual 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:548
virtual bool make_directory(const Filename &file)
Attempts to create the indicated file within the mount, if it does not already exist.
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...
This class records a particular byte sub-range within an existing file on disk.
Definition: subfileInfo.h:29
virtual void close_write_file(ostream *stream)
Closes a file opened by a previous call to open_write_file().
static bool simple_read_file(istream *stream, pvector< unsigned char > &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:85
static void close_write_file(ostream *stream)
Closes a file opened by a previous call to open_write_file().
virtual void close_read_write_file(iostream *stream)
Closes a file opened by a previous call to open_read_write_file().
virtual bool atomic_compare_and_exchange_contents(const Filename &file, string &orig_contents, const string &old_contents, const string &new_contents)
See Filename::atomic_compare_and_exchange_contents().
A simple file or directory within the VirtualFileSystem: this maps to exactly one file on one mount p...
virtual 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 iostream * open_read_write_file(const Filename &file, bool truncate)
Opens the file for writing.