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