Panda3D
 All Classes Functions Variables Enumerations
virtualFileMountMultifile.cxx
00001 // Filename: virtualFileMountMultifile.cxx
00002 // Created by:  drose (03Aug02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "virtualFileMountMultifile.h"
00016 #include "virtualFileSystem.h"
00017 
00018 TypeHandle VirtualFileMountMultifile::_type_handle;
00019 
00020 
00021 ////////////////////////////////////////////////////////////////////
00022 //     Function: VirtualFileMountMultifile::Destructor
00023 //       Access: Public, Virtual
00024 //  Description: 
00025 ////////////////////////////////////////////////////////////////////
00026 VirtualFileMountMultifile::
00027 ~VirtualFileMountMultifile() {
00028 }
00029 
00030 
00031 ////////////////////////////////////////////////////////////////////
00032 //     Function: VirtualFileMountMultifile::has_file
00033 //       Access: Public, Virtual
00034 //  Description: Returns true if the indicated file exists within the
00035 //               mount system.
00036 ////////////////////////////////////////////////////////////////////
00037 bool VirtualFileMountMultifile::
00038 has_file(const Filename &file) const {
00039   return (file.empty() ||
00040           _multifile->find_subfile(file) >= 0 ||
00041           _multifile->has_directory(file));
00042 }
00043 
00044 ////////////////////////////////////////////////////////////////////
00045 //     Function: VirtualFileMountMultifile::is_directory
00046 //       Access: Public, Virtual
00047 //  Description: Returns true if the indicated file exists within the
00048 //               mount system and is a directory.
00049 ////////////////////////////////////////////////////////////////////
00050 bool VirtualFileMountMultifile::
00051 is_directory(const Filename &file) const {
00052   return (file.empty() || _multifile->has_directory(file));
00053 }
00054 
00055 ////////////////////////////////////////////////////////////////////
00056 //     Function: VirtualFileMountMultifile::is_regular_file
00057 //       Access: Public, Virtual
00058 //  Description: Returns true if the indicated file exists within the
00059 //               mount system and is a regular file.
00060 ////////////////////////////////////////////////////////////////////
00061 bool VirtualFileMountMultifile::
00062 is_regular_file(const Filename &file) const {
00063   return (_multifile->find_subfile(file) >= 0);
00064 }
00065 
00066 ////////////////////////////////////////////////////////////////////
00067 //     Function: VirtualFileMountMultifile::read_file
00068 //       Access: Public, Virtual
00069 //  Description: Fills up the indicated pvector with the contents of
00070 //               the file, if it is a regular file.  Returns true on
00071 //               success, false otherwise.
00072 ////////////////////////////////////////////////////////////////////
00073 bool VirtualFileMountMultifile::
00074 read_file(const Filename &file, bool do_uncompress,
00075           pvector<unsigned char> &result) const {
00076   if (do_uncompress) {
00077     // If the file is to be decompressed, we'd better just use the
00078     // higher-level implementation, which includes support for
00079     // on-the-fly decompression.
00080     return VirtualFileMount::read_file(file, do_uncompress, result);
00081   }
00082 
00083   // But if we're just reading a straight file, let the Multifile do
00084   // the reading, which avoids a few levels of buffer copies.
00085 
00086   int subfile_index = _multifile->find_subfile(file);
00087   if (subfile_index < 0) {
00088     express_cat.info()
00089       << "Unable to read " << file << "\n";
00090     return false;
00091   }
00092 
00093   return _multifile->read_subfile(subfile_index, result);
00094 }
00095 
00096 ////////////////////////////////////////////////////////////////////
00097 //     Function: VirtualFileMountMultifile::open_read_file
00098 //       Access: Public, Virtual
00099 //  Description: Opens the file for reading, if it exists.  Returns a
00100 //               newly allocated istream on success (which you should
00101 //               eventually delete when you are done reading).
00102 //               Returns NULL on failure.
00103 ////////////////////////////////////////////////////////////////////
00104 istream *VirtualFileMountMultifile::
00105 open_read_file(const Filename &file) const {
00106   int subfile_index = _multifile->find_subfile(file);
00107   if (subfile_index < 0) {
00108     return NULL;
00109   }
00110 
00111   // The caller will eventually pass this pointer to
00112   // VirtualFileSystem::close_read_file(), not to
00113   // Multifile::close_read_subfile().  Fortunately, these two methods
00114   // do the same thing, so that doesn't matter.
00115   return _multifile->open_read_subfile(subfile_index);
00116 }
00117 
00118 ////////////////////////////////////////////////////////////////////
00119 //     Function: VirtualFileMountMultifile::get_file_size
00120 //       Access: Published, Virtual
00121 //  Description: Returns the current size on disk (or wherever it is)
00122 //               of the already-open file.  Pass in the stream that
00123 //               was returned by open_read_file(); some
00124 //               implementations may require this stream to determine
00125 //               the size.
00126 ////////////////////////////////////////////////////////////////////
00127 off_t VirtualFileMountMultifile::
00128 get_file_size(const Filename &file, istream *) const {
00129   int subfile_index = _multifile->find_subfile(file);
00130   if (subfile_index < 0) {
00131     return 0;
00132   }
00133   return _multifile->get_subfile_length(subfile_index);
00134 }
00135 
00136 ////////////////////////////////////////////////////////////////////
00137 //     Function: VirtualFileMountMultifile::get_file_size
00138 //       Access: Published, Virtual
00139 //  Description: Returns the current size on disk (or wherever it is)
00140 //               of the file before it has been opened.
00141 ////////////////////////////////////////////////////////////////////
00142 off_t VirtualFileMountMultifile::
00143 get_file_size(const Filename &file) const {
00144   int subfile_index = _multifile->find_subfile(file);
00145   if (subfile_index < 0) {
00146     return 0;
00147   }
00148   return _multifile->get_subfile_length(subfile_index);
00149 }
00150 
00151 ////////////////////////////////////////////////////////////////////
00152 //     Function: VirtualFileMountMultifile::get_timestamp
00153 //       Access: Published, Virtual
00154 //  Description: Returns a time_t value that represents the time the
00155 //               file was last modified, to within whatever precision
00156 //               the operating system records this information (on a
00157 //               Windows95 system, for instance, this may only be
00158 //               accurate to within 2 seconds).
00159 //
00160 //               If the timestamp cannot be determined, either because
00161 //               it is not supported by the operating system or
00162 //               because there is some error (such as file not found),
00163 //               returns 0.
00164 ////////////////////////////////////////////////////////////////////
00165 time_t VirtualFileMountMultifile::
00166 get_timestamp(const Filename &file) const {
00167   int subfile_index = _multifile->find_subfile(file);
00168   if (subfile_index < 0) {
00169     return 0;
00170   }
00171   return _multifile->get_subfile_timestamp(subfile_index);
00172 }
00173 
00174 ////////////////////////////////////////////////////////////////////
00175 //     Function: VirtualFileMountMultifile::get_system_info
00176 //       Access: Public, Virtual
00177 //  Description: Populates the SubfileInfo structure with the data
00178 //               representing where the file actually resides on disk,
00179 //               if this is knowable.  Returns true if the file might
00180 //               reside on disk, and the info is populated, or false
00181 //               if it might not (or it is not known where the file
00182 //               resides), in which case the info is meaningless.
00183 ////////////////////////////////////////////////////////////////////
00184 bool VirtualFileMountMultifile::
00185 get_system_info(const Filename &file, SubfileInfo &info) {
00186   Filename multifile_name = _multifile->get_multifile_name();
00187   if (multifile_name.empty()) {
00188     return false;
00189   }
00190   int subfile_index = _multifile->find_subfile(file);
00191   if (subfile_index < 0) {
00192     return false;
00193   }
00194   if (_multifile->is_subfile_compressed(subfile_index) ||
00195       _multifile->is_subfile_encrypted(subfile_index)) {
00196     return false;
00197   }
00198 
00199   streampos start = _multifile->get_subfile_internal_start(subfile_index);
00200   size_t length = _multifile->get_subfile_internal_length(subfile_index);
00201 
00202   info = SubfileInfo(multifile_name, start, length); 
00203   return true;
00204 }
00205 
00206 ////////////////////////////////////////////////////////////////////
00207 //     Function: VirtualFileMountMultifile::scan_directory
00208 //       Access: Public, Virtual
00209 //  Description: Fills the given vector up with the list of filenames
00210 //               that are local to this directory, if the filename is
00211 //               a directory.  Returns true if successful, or false if
00212 //               the file is not a directory or cannot be read.
00213 ////////////////////////////////////////////////////////////////////
00214 bool VirtualFileMountMultifile::
00215 scan_directory(vector_string &contents, const Filename &dir) const {
00216   return _multifile->scan_directory(contents, dir);
00217 }
00218 
00219 
00220 ////////////////////////////////////////////////////////////////////
00221 //     Function: VirtualFileMountMultifile::output
00222 //       Access: Public, Virtual
00223 //  Description: 
00224 ////////////////////////////////////////////////////////////////////
00225 void VirtualFileMountMultifile::
00226 output(ostream &out) const {
00227   out << _multifile->get_multifile_name();
00228 }
 All Classes Functions Variables Enumerations