Panda3D
virtualFileMountMultifile.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 virtualFileMountMultifile.cxx
10  * @author drose
11  * @date 2002-08-03
12  */
13 
15 #include "virtualFileSystem.h"
16 
17 TypeHandle VirtualFileMountMultifile::_type_handle;
18 
19 
20 /**
21  *
22  */
23 VirtualFileMountMultifile::
24 ~VirtualFileMountMultifile() {
25 }
26 
27 
28 /**
29  * Returns true if the indicated file exists within the mount system.
30  */
32 has_file(const Filename &file) const {
33  return (file.empty() ||
34  _multifile->find_subfile(file) >= 0 ||
35  _multifile->has_directory(file));
36 }
37 
38 /**
39  * Returns true if the indicated file exists within the mount system and is a
40  * directory.
41  */
43 is_directory(const Filename &file) const {
44  return (file.empty() || _multifile->has_directory(file));
45 }
46 
47 /**
48  * Returns true if the indicated file exists within the mount system and is a
49  * regular file.
50  */
52 is_regular_file(const Filename &file) const {
53  return (_multifile->find_subfile(file) >= 0);
54 }
55 
56 /**
57  * Fills up the indicated pvector with the contents of the file, if it is a
58  * regular file. Returns true on success, false otherwise.
59  */
61 read_file(const Filename &file, bool do_uncompress,
62  vector_uchar &result) const {
63  if (do_uncompress) {
64  // If the file is to be decompressed, we'd better just use the higher-
65  // level implementation, which includes support for on-the-fly
66  // decompression.
67  return VirtualFileMount::read_file(file, do_uncompress, result);
68  }
69 
70  // But if we're just reading a straight file, let the Multifile do the
71  // reading, which avoids a few levels of buffer copies.
72 
73  int subfile_index = _multifile->find_subfile(file);
74  if (subfile_index < 0) {
75  express_cat.info()
76  << "Unable to read " << file << "\n";
77  return false;
78  }
79 
80  return _multifile->read_subfile(subfile_index, result);
81 }
82 
83 /**
84  * Opens the file for reading, if it exists. Returns a newly allocated
85  * istream on success (which you should eventually delete when you are done
86  * reading). Returns NULL on failure.
87  */
88 std::istream *VirtualFileMountMultifile::
89 open_read_file(const Filename &file) const {
90  int subfile_index = _multifile->find_subfile(file);
91  if (subfile_index < 0) {
92  return nullptr;
93  }
94 
95  // The caller will eventually pass this pointer to
96  // VirtualFileSystem::close_read_file(), not to
97  // Multifile::close_read_subfile(). Fortunately, these two methods do the
98  // same thing, so that doesn't matter.
99  return _multifile->open_read_subfile(subfile_index);
100 }
101 
102 /**
103  * Returns the current size on disk (or wherever it is) of the already-open
104  * file. Pass in the stream that was returned by open_read_file(); some
105  * implementations may require this stream to determine the size.
106  */
107 std::streamsize VirtualFileMountMultifile::
108 get_file_size(const Filename &file, std::istream *) const {
109  int subfile_index = _multifile->find_subfile(file);
110  if (subfile_index < 0) {
111  return 0;
112  }
113  return _multifile->get_subfile_length(subfile_index);
114 }
115 
116 /**
117  * Returns the current size on disk (or wherever it is) of the file before it
118  * has been opened.
119  */
120 std::streamsize VirtualFileMountMultifile::
121 get_file_size(const Filename &file) const {
122  int subfile_index = _multifile->find_subfile(file);
123  if (subfile_index < 0) {
124  return 0;
125  }
126  return _multifile->get_subfile_length(subfile_index);
127 }
128 
129 /**
130  * Returns a time_t value that represents the time the file was last modified,
131  * to within whatever precision the operating system records this information
132  * (on a Windows95 system, for instance, this may only be accurate to within 2
133  * seconds).
134  *
135  * If the timestamp cannot be determined, either because it is not supported
136  * by the operating system or because there is some error (such as file not
137  * found), returns 0.
138  */
140 get_timestamp(const Filename &file) const {
141  int subfile_index = _multifile->find_subfile(file);
142  if (subfile_index < 0) {
143  return 0;
144  }
145  return _multifile->get_subfile_timestamp(subfile_index);
146 }
147 
148 /**
149  * Populates the SubfileInfo structure with the data representing where the
150  * file actually resides on disk, if this is knowable. Returns true if the
151  * file might reside on disk, and the info is populated, or false if it might
152  * not (or it is not known where the file resides), in which case the info is
153  * meaningless.
154  */
156 get_system_info(const Filename &file, SubfileInfo &info) {
157  Filename multifile_name = _multifile->get_multifile_name();
158  if (multifile_name.empty()) {
159  return false;
160  }
161  int subfile_index = _multifile->find_subfile(file);
162  if (subfile_index < 0) {
163  return false;
164  }
165  if (_multifile->is_subfile_compressed(subfile_index) ||
166  _multifile->is_subfile_encrypted(subfile_index)) {
167  return false;
168  }
169 
170  std::streampos start = _multifile->get_subfile_internal_start(subfile_index);
171  size_t length = _multifile->get_subfile_internal_length(subfile_index);
172 
173  info = SubfileInfo(multifile_name, start, length);
174  return true;
175 }
176 
177 /**
178  * Fills the given vector up with the list of filenames that are local to this
179  * directory, if the filename is a directory. Returns true if successful, or
180  * false if the file is not a directory or cannot be read.
181  */
183 scan_directory(vector_string &contents, const Filename &dir) const {
184  return _multifile->scan_directory(contents, dir);
185 }
186 
187 
188 /**
189  *
190  */
191 void VirtualFileMountMultifile::
192 output(std::ostream &out) const {
193  out << _multifile->get_multifile_name();
194 }
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 bool is_regular_file(const Filename &file) const
Returns true if the indicated file exists within the mount system and is a regular file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool is_directory(const Filename &file) const
Returns true if the indicated file exists within the mount system and is a directory.
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
virtual time_t get_timestamp(const Filename &file) const
Returns a time_t value that represents the time the file was last modified, to within whatever precis...
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...
virtual std::istream * open_read_file(const Filename &file) const
Opens the file for reading, if it exists.
virtual std::streamsize get_file_size(const Filename &file, std::istream *stream) const
Returns the current size on disk (or wherever it is) of the already-open file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool scan_directory(vector_string &contents, const Filename &dir) const
Fills the given vector up with the list of filenames that are local to this directory,...
This class records a particular byte sub-range within an existing file on disk.
Definition: subfileInfo.h:26
virtual bool has_file(const Filename &file) const
Returns true if the indicated file exists within the mount system.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
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.