Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

Multifile Class Reference

A file that contains a set of files. More...

#include <multifile.h>

List of all members.

Public Member Functions

 Multifile ()
 ~Multifile ()
bool open_read (const Filename &multifile_name)
 Opens the named Multifile on disk for reading.

bool open_write (const Filename &multifile_name)
 Opens the named Multifile on disk for writing.

bool open_read_write (const Filename &multifile_name)
 Opens the named Multifile on disk for reading and writing.

void close ()
 Closes the Multifile if it is open.

const Filenameget_multifile_name () const
 Returns the filename of the Multifile, if it is available.

bool is_read_valid () const
 Returns true if the Multifile has been opened for read mode and there have been no errors, and individual Subfile contents may be extracted.

bool is_write_valid () const
 Returns true if the Multifile has been opened for write mode and there have been no errors, and Subfiles may be added or removed from the Multifile.

bool needs_repack () const
 Returns true if the Multifile index is suboptimal and should be repacked.

void set_scale_factor (size_t scale_factor)
 Changes the internal scale factor for this Multifile.

size_t get_scale_factor () const
 Returns the internal scale factor for this Multifile.

string add_subfile (const string &subfile_name, const Filename &filename, int compression_level)
 Adds a file on disk as a subfile to the Multifile.

bool flush ()
 Writes all contents of the Multifile to disk.

bool repack ()
 Forces a complete rewrite of the Multifile and all of its contents, so that its index will appear at the beginning of the file with all of the subfiles listed in alphabetical order.

int get_num_subfiles () const
 Returns the number of subfiles within the Multifile.

int find_subfile (const string &subfile_name) const
 Returns the index of the subfile with the indicated name, or -1 if the named subfile is not within the Multifile.

bool has_directory (const string &subfile_name) const
 Returns true if the indicated subfile name is the directory prefix to one or more files within the Multifile.

bool scan_directory (vector_string &contents, const string &subfile_name) const
 Considers subfile_name to be the name of a subdirectory within the Multifile, but not a file itself; ills the given vector up with the sorted list of subdirectories or files within the named directory.

void remove_subfile (int index)
 Removes the nth subfile from the Multifile.

const string & get_subfile_name (int index) const
 Returns the name of the nth subfile.

size_t get_subfile_length (int index) const
 Returns the uncompressed data length of the nth subfile.

bool is_subfile_compressed (int index) const
 Returns true if the indicated subfile has been compressed when stored within the archive, false otherwise.

size_t get_subfile_compressed_length (int index) const
 Returns the number of bytes the indicated subfile consumes within the archive.

string read_subfile (int index)
 Returns a string that contains the entire contents of the indicated subfile.

istream * open_read_subfile (int index)
 Returns an istream that may be used to read the indicated subfile.

bool extract_subfile (int index, const Filename &filename)
 Extracts the nth subfile into a file with the given name.

void output (ostream &out) const
void ls (ostream &out=cout) const
 Shows a list of all subfiles within the Multifile.

bool read_subfile (int index, string &result)
 Fills a string with the entire contents of the indicated subfile.

bool open_read (istream *multifile_stream)
 Opens an anonymous Multifile for reading using an istream.

bool open_write (ostream *multifile_stream)
 Opens an anonymous Multifile for writing using an ostream.

bool open_read_write (iostream *multifile_stream)
 Opens an anonymous Multifile for reading and writing using an iostream.

string add_subfile (const string &subfile_name, istream *subfile_data, int compression_level)
 Adds a file on disk as a subfile to the Multifile.

bool extract_subfile_to (int index, ostream &out)
 Extracts the nth subfile to the indicated ostream.


Private Types

typedef ov_set< Subfile *,
IndirectLess< Subfile > > 
Subfiles
typedef pvector< Subfile * > PendingSubfiles
enum  SubfileFlags { SF_deleted = 0x0001, SF_index_invalid = 0x0002, SF_data_invalid = 0x0004, SF_compressed = 0x0008 }

Private Member Functions

 Multifile (const Multifile &copy)
 Don't try to copy Multifiles.

void operator= (const Multifile &copy)
 Don't try to copy Multifiles.

streampos word_to_streampos (size_t word) const
 Converts a size_t address read from the file to a streampos byte address within the file.

size_t streampos_to_word (streampos fpos) const
 Converts a streampos byte address within the file to a size_t value suitable for writing to the file.

streampos normalize_streampos (streampos fpos) const
 Rounds the streampos byte address up to the next multiple of _scale_factor.

streampos pad_to_streampos (streampos fpos)
 Assumes the _write pointer is at the indicated fpos, rounds the fpos up to the next legitimate address (using normalize_streampos()), and writes enough zeros to the stream to fill the gap.

string add_new_subfile (const string &subfile_name, Subfile *subfile, int compression_level)
 Adds a newly-allocated Subfile pointer to the Multifile.

void clear_subfiles ()
 Removes the set of subfiles from the tables and frees their associated memory.

bool read_index ()
 Reads the Multifile header and index.

bool write_header ()
 Writes just the header part of the Multifile, not the index.


Private Attributes

Subfiles _subfiles
PendingSubfiles _new_subfiles
PendingSubfiles _removed_subfiles
istream * _read
ostream * _write
streampos _next_index
streampos _last_index
bool _needs_repack
size_t _scale_factor
size_t _new_scale_factor
ifstream _read_file
ofstream _write_file
fstream _read_write_file
Filename _multifile_name
int _file_major_ver
int _file_minor_ver

Static Private Attributes

const char _header [] = "pmf\0\n\r"
const size_t _header_size = 6
const int _current_major_ver = 1
const int _current_minor_ver = 0

Friends

class Subfile


Detailed Description

A file that contains a set of files.

Definition at line 40 of file multifile.h.


Member Typedef Documentation

typedef pvector<Subfile *> Multifile::PendingSubfiles [private]
 

Definition at line 147 of file multifile.h.

typedef ov_set<Subfile *, IndirectLess<Subfile> > Multifile::Subfiles [private]
 

Definition at line 145 of file multifile.h.


Member Enumeration Documentation

enum Multifile::SubfileFlags [private]
 

Enumeration values:
SF_deleted 
SF_index_invalid 
SF_data_invalid 
SF_compressed 

Definition at line 100 of file multifile.h.


Constructor & Destructor Documentation

Multifile::Multifile  ) 
 

Definition at line 93 of file multifile.cxx.

References _file_major_ver, _file_minor_ver, _needs_repack, _new_scale_factor, and _scale_factor.

Multifile::~Multifile  ) 
 

Definition at line 113 of file multifile.cxx.

References nassertv.

Multifile::Multifile const Multifile &  copy  )  [private]
 

Don't try to copy Multifiles.

Definition at line 126 of file multifile.cxx.

References nassertv.


Member Function Documentation

string Multifile::add_new_subfile const string &  subfile_name,
Subfile subfile,
int  compression_level
[private]
 

Adds a newly-allocated Subfile pointer to the Multifile.

Definition at line 1262 of file multifile.cxx.

Referenced by open_read_subfile().

string Multifile::add_subfile const string &  subfile_name,
istream *  subfile_data,
int  compression_level
 

Adds a file on disk as a subfile to the Multifile.

The indicated istream will be read and its contents added to the Multifile at the next call to flush().

Returns the subfile name on success (it might have been modified slightly), or empty string on failure.

Definition at line 1182 of file multifile.cxx.

References _current_major_ver, _current_minor_ver, _header, _header_size, _last_index, _multifile_name, _next_index, _scale_factor, _write, close(), nassertr, NULL, pad_to_streampos(), and writer().

string Multifile::add_subfile const string &  subfile_name,
const Filename filename,
int  compression_level
 

Adds a file on disk as a subfile to the Multifile.

The file named by filename will be read and added to the Multifile at the next call to flush().

Returns the subfile name on success (it might have been modified slightly), or empty string on failure.

Definition at line 382 of file multifile.cxx.

References writer().

void Multifile::clear_subfiles  )  [private]
 

Removes the set of subfiles from the tables and frees their associated memory.

Definition at line 1320 of file multifile.cxx.

References nassertr, and NULL.

void Multifile::close  ) 
 

Closes the Multifile if it is open.

All changes are flushed to disk, and the file becomes invalid for further operations until the next call to open().

Definition at line 272 of file multifile.cxx.

References _new_scale_factor, _next_index, _scale_factor, is_read_valid(), is_write_valid(), nassertv, scale_factor, and size_t.

Referenced by add_subfile(), flush(), get_subfile_compressed_length(), is_subfile_compressed(), open_read(), and operator=().

bool Multifile::extract_subfile int  index,
const Filename filename
 

Extracts the nth subfile into a file with the given name.

Definition at line 994 of file multifile.cxx.

bool Multifile::extract_subfile_to int  index,
ostream &  out
 

Extracts the nth subfile to the indicated ostream.

Definition at line 1201 of file multifile.cxx.

int Multifile::find_subfile const string &  subfile_name  )  const
 

Returns the index of the subfile with the indicated name, or -1 if the named subfile is not within the Multifile.

Definition at line 670 of file multifile.cxx.

References _subfiles.

Referenced by VirtualFileMountMultifile::is_directory().

bool Multifile::flush void   ) 
 

Writes all contents of the Multifile to disk.

Until flush() is called, add_subfile() and remove_subfile() do not actually do anything to disk. At this point, all of the recently-added subfiles are read and their contents are added to the end of the Multifile, and the recently-removed subfiles are marked gone from the Multifile.

This may result in a suboptimal index. To guarantee that the index is written at the beginning of the file, call repack() instead of flush().

It is not necessary to call flush() explicitly unless you are concerned about reading the recently-added subfiles immediately.

Returns true on success, false on failure.

Definition at line 437 of file multifile.cxx.

References _last_index, _multifile_name, _new_scale_factor, _new_subfiles, _next_index, _removed_subfiles, _scale_factor, _subfiles, _write, close(), Filename::empty(), Filename::get_dirname(), is_read_valid(), is_write_valid(), nassertr, open_read_write(), Filename::open_write(), Filename::rename_to(), Filename::set_binary(), Filename::temporary(), and Filename::unlink().

Referenced by scan_directory().

const Filename & Multifile::get_multifile_name  )  const [inline]
 

Returns the filename of the Multifile, if it is available.

Definition at line 34 of file multifile.I.

References _read, INLINE, and NULL.

int Multifile::get_num_subfiles  )  const
 

Returns the number of subfiles within the Multifile.

The subfiles may be accessed in alphabetical order by iterating through [0 .. get_num_subfiles()).

Definition at line 653 of file multifile.cxx.

References _needs_repack, _removed_subfiles, _subfiles, and SF_deleted.

Referenced by get_subfile_name().

size_t Multifile::get_scale_factor  )  const [inline]
 

Returns the internal scale factor for this Multifile.

See set_scale_factor().

Definition at line 98 of file multifile.I.

References _scale_factor.

size_t Multifile::get_subfile_compressed_length int  index  )  const
 

Returns the number of bytes the indicated subfile consumes within the archive.

For compressed subfiles, this will generally be smaller than get_subfile_length(); for noncompressed subfiles, it will be equal.

Definition at line 889 of file multifile.cxx.

References _write, and close().

size_t Multifile::get_subfile_length int  index  )  const
 

Returns the uncompressed data length of the nth subfile.

This might return 0 if the subfile has recently been added and flush() has not yet been called.

Definition at line 849 of file multifile.cxx.

References NULL.

const string & Multifile::get_subfile_name int  index  )  const
 

Returns the name of the nth subfile.

Definition at line 826 of file multifile.cxx.

References get_num_subfiles().

bool Multifile::has_directory const string &  subfile_name  )  const
 

Returns true if the indicated subfile name is the directory prefix to one or more files within the Multifile.

That is, the Multifile contains at least one file named "subfile_name/...".

Definition at line 697 of file multifile.cxx.

References _subfiles, nassertr, and SF_compressed.

Referenced by VirtualFileMountMultifile::has_file().

bool Multifile::is_read_valid  )  const [inline]
 

Returns true if the Multifile has been opened for read mode and there have been no errors, and individual Subfile contents may be extracted.

Definition at line 51 of file multifile.I.

References _write, and NULL.

Referenced by close(), and flush().

bool Multifile::is_subfile_compressed int  index  )  const
 

Returns true if the indicated subfile has been compressed when stored within the archive, false otherwise.

Definition at line 867 of file multifile.cxx.

References _read, close(), and read_index().

bool Multifile::is_write_valid  )  const [inline]
 

Returns true if the Multifile has been opened for write mode and there have been no errors, and Subfiles may be added or removed from the Multifile.

Definition at line 68 of file multifile.I.

References _new_scale_factor, INLINE, and size_t.

Referenced by close(), flush(), and open_read_subfile().

void Multifile::ls ostream &  out = cout  )  const
 

Shows a list of all subfiles within the Multifile.

Definition at line 1034 of file multifile.cxx.

bool Multifile::needs_repack  )  const [inline]
 

Returns true if the Multifile index is suboptimal and should be repacked.

Call repack() to achieve this.

Definition at line 83 of file multifile.I.

References INLINE, and read_subfile().

streampos Multifile::normalize_streampos streampos  fpos  )  const [inline, private]
 

Rounds the streampos byte address up to the next multiple of _scale_factor.

Only multiples of _scale_factor may be written to the file.

Definition at line 162 of file multifile.I.

References INLINE, and SF_index_invalid.

bool Multifile::open_read istream *  multifile_stream  ) 
 

Opens an anonymous Multifile for reading using an istream.

There must be seek functionality via seekg() and tellg() on the istream.

This version of open_read() does not close the istream when Multifile::close() is called.

Definition at line 1093 of file multifile.cxx.

References _multifile_name.

bool Multifile::open_read const Filename multifile_name  ) 
 

Opens the named Multifile on disk for reading.

The Multifile index is read in, and the list of subfiles becomes available; individual subfiles may then be extracted or read, but the list of subfiles may not be modified.

Also see the version of open_read() which accepts an istream. Returns true on success, false on failure.

Definition at line 166 of file multifile.cxx.

References _multifile_name, _write, _write_file, close(), multifile_name, Filename::open_write(), and Filename::set_binary().

Referenced by VirtualFileSystem::mount(), and Extractor::~Extractor().

istream * Multifile::open_read_subfile int  index  ) 
 

Returns an istream that may be used to read the indicated subfile.

You may seek() within this istream to your heart's content; even though it will be a reference to the already-opened fstream of the Multifile itself, byte 0 appears to be the beginning of the subfile and EOF appears to be the end of the subfile.

The returned istream will have been allocated via new; you should delete it when you are finished reading the subfile.

Any future calls to repack() or close() (or the Multifile destructor) will invalidate all currently open subfile pointers.

The return value will be NULL if the stream cannot be opened for some reason.

Definition at line 937 of file multifile.cxx.

References Multifile::Subfile::_source, add_new_subfile(), is_write_valid(), and nassertr.

bool Multifile::open_read_write iostream *  multifile_stream  ) 
 

Opens an anonymous Multifile for reading and writing using an iostream.

There must be seek functionality via seekg()/seekp() and tellg()/tellp() on the iostream.

This version of open_read_write() does not close the iostream when Multifile::close() is called.

Definition at line 1145 of file multifile.cxx.

bool Multifile::open_read_write const Filename multifile_name  ) 
 

Opens the named Multifile on disk for reading and writing.

If there already exists a file by that name, its index is read. Subfiles may be added or removed, and the resulting changes will be written to the named file.

Also see the version of open_read_write() which accepts an iostream. Returns true on success, false on failure.

Definition at line 240 of file multifile.cxx.

References _multifile_name, _read_file, _read_write_file, and _write_file.

Referenced by flush().

bool Multifile::open_write ostream *  multifile_stream  ) 
 

Opens an anonymous Multifile for writing using an ostream.

There must be seek functionality via seekp() and tellp() on the pstream.

This version of open_write() does not close the ostream when Multifile::close() is called.

Definition at line 1118 of file multifile.cxx.

References _current_major_ver, _current_minor_ver, _file_major_ver, _file_minor_ver, and _multifile_name.

bool Multifile::open_write const Filename multifile_name  ) 
 

Opens the named Multifile on disk for writing.

If there already exists a file by that name, it is truncated. The Multifile is then prepared for accepting a brand new set of subfiles, which will be written to the indicated filename. Individual subfiles may not be extracted or read.

Also see the version of open_write() which accepts an ostream. Returns true on success, false on failure.

Definition at line 203 of file multifile.cxx.

References _multifile_name, _read, _read_write_file, _write, multifile_name, and read_index().

void Multifile::operator= const Multifile &  copy  )  [private]
 

Don't try to copy Multifiles.

Definition at line 139 of file multifile.cxx.

References _multifile_name, _read, _read_file, close(), multifile_name, Filename::open_read(), read_index(), and Filename::set_binary().

void Multifile::output ostream &  out  )  const
 

Definition at line 1020 of file multifile.cxx.

References _needs_repack.

streampos Multifile::pad_to_streampos streampos  fpos  )  [private]
 

Assumes the _write pointer is at the indicated fpos, rounds the fpos up to the next legitimate address (using normalize_streampos()), and writes enough zeros to the stream to fill the gap.

Returns the new fpos.

Definition at line 1240 of file multifile.cxx.

References reader(), and SF_compressed.

Referenced by add_subfile().

bool Multifile::read_index  )  [private]
 

Reads the Multifile header and index.

Returns true if successful, false if the Multifile is not valid.

Definition at line 1352 of file multifile.cxx.

References SF_data_invalid.

Referenced by is_subfile_compressed(), open_write(), and operator=().

bool Multifile::read_subfile int  index,
string &  result
 

Fills a string with the entire contents of the indicated subfile.

Definition at line 1053 of file multifile.cxx.

References _new_subfiles, _removed_subfiles, _subfiles, _write, and Multifile::Subfile::rewrite_index_flags().

string Multifile::read_subfile int  index  )  [inline]
 

Returns a string that contains the entire contents of the indicated subfile.

Definition at line 113 of file multifile.I.

References INLINE, streampos_to_word(), and word_to_streampos().

Referenced by needs_repack().

void Multifile::remove_subfile int  index  ) 
 

Removes the nth subfile from the Multifile.

This will cause all subsequent index numbers to decrease by one. The file will not actually be removed from the disk until the next call to flush().

Note that this does not actually remove the data from the indicated subfile; it simply removes it from the index. The Multifile will not be reduced in size after this operation, until the next call to repack().

Definition at line 806 of file multifile.cxx.

bool Multifile::repack  ) 
 

Forces a complete rewrite of the Multifile and all of its contents, so that its index will appear at the beginning of the file with all of the subfiles listed in alphabetical order.

This is considered optimal for reading, and is the standard configuration; but it is not essential to do this.

It is only valid to call this if the Multifile was opened using open_read_write() and an explicit filename, rather than an iostream. Also, we must have write permission to the directory containing the Multifile.

Returns true on success, false on failure.

Definition at line 571 of file multifile.cxx.

bool Multifile::scan_directory vector_string &  contents,
const string &  subfile_name
const
 

Considers subfile_name to be the name of a subdirectory within the Multifile, but not a file itself; ills the given vector up with the sorted list of subdirectories or files within the named directory.

Note that directories do not exist explicitly within a Multifile; this just checks for the existence of files with the given initial prefix.

Returns true if successful, false otherwise.

Definition at line 747 of file multifile.cxx.

References flush(), nassertr, and NULL.

void Multifile::set_scale_factor size_t  scale_factor  ) 
 

Changes the internal scale factor for this Multifile.

This is normally 1, but it may be set to any arbitrary value (greater than zero) to support Multifile archives that exceed 4GB, if necessary. (Individual subfiles may still not exceed 4GB.)

All addresses within the file are rounded up to the next multiple of _scale_factor, and zeros are written to the file to fill the resulting gaps. Then the address is divided by _scale_factor and written out as a 32-bit integer. Thus, setting a scale factor of 2 supports up to 8GB files, 3 supports 12GB files, etc.

Calling this function on an already-existing Multifile will have no immediate effect until a future call to repack() or close() (or until the Multifile is destructed).

Definition at line 344 of file multifile.cxx.

References _next_index, and write_header().

size_t Multifile::streampos_to_word streampos  fpos  )  const [inline, private]
 

Converts a streampos byte address within the file to a size_t value suitable for writing to the file.

Definition at line 145 of file multifile.I.

References Multifile::Subfile::_name.

Referenced by read_subfile().

streampos Multifile::word_to_streampos size_t  word  )  const [inline, private]
 

Converts a size_t address read from the file to a streampos byte address within the file.

Definition at line 130 of file multifile.I.

References NULL.

Referenced by read_subfile().

bool Multifile::write_header  )  [private]
 

Writes just the header part of the Multifile, not the index.

Definition at line 1452 of file multifile.cxx.

References writer().

Referenced by set_scale_factor().


Friends And Related Function Documentation

friend class Subfile [friend]
 

Definition at line 173 of file multifile.h.


Member Data Documentation

const int Multifile::_current_major_ver = 1 [static, private]
 

Definition at line 40 of file multifile.cxx.

Referenced by add_subfile(), and open_write().

const int Multifile::_current_minor_ver = 0 [static, private]
 

Definition at line 41 of file multifile.cxx.

Referenced by add_subfile(), and open_write().

int Multifile::_file_major_ver [private]
 

Definition at line 165 of file multifile.h.

Referenced by Multifile(), and open_write().

int Multifile::_file_minor_ver [private]
 

Definition at line 166 of file multifile.h.

Referenced by Multifile(), and open_write().

const char Multifile::_header = "pmf\0\n\r" [static, private]
 

Definition at line 34 of file multifile.cxx.

Referenced by add_subfile().

const size_t Multifile::_header_size = 6 [static, private]
 

Definition at line 35 of file multifile.cxx.

Referenced by add_subfile().

streampos Multifile::_last_index [private]
 

Definition at line 154 of file multifile.h.

Referenced by add_subfile(), and flush().

Filename Multifile::_multifile_name [private]
 

Definition at line 163 of file multifile.h.

Referenced by add_subfile(), flush(), open_read(), open_read_write(), open_write(), and operator=().

bool Multifile::_needs_repack [private]
 

Definition at line 156 of file multifile.h.

Referenced by get_num_subfiles(), Multifile(), and output().

size_t Multifile::_new_scale_factor [private]
 

Definition at line 158 of file multifile.h.

Referenced by close(), flush(), is_write_valid(), and Multifile().

PendingSubfiles Multifile::_new_subfiles [private]
 

Definition at line 148 of file multifile.h.

Referenced by flush(), and read_subfile().

streampos Multifile::_next_index [private]
 

Definition at line 153 of file multifile.h.

Referenced by add_subfile(), close(), flush(), and set_scale_factor().

istream* Multifile::_read [private]
 

Definition at line 151 of file multifile.h.

Referenced by get_multifile_name(), is_subfile_compressed(), open_write(), and operator=().

ifstream Multifile::_read_file [private]
 

Definition at line 160 of file multifile.h.

Referenced by open_read_write(), and operator=().

fstream Multifile::_read_write_file [private]
 

Definition at line 162 of file multifile.h.

Referenced by open_read_write(), and open_write().

PendingSubfiles Multifile::_removed_subfiles [private]
 

Definition at line 149 of file multifile.h.

Referenced by flush(), get_num_subfiles(), and read_subfile().

size_t Multifile::_scale_factor [private]
 

Definition at line 157 of file multifile.h.

Referenced by add_subfile(), close(), flush(), get_scale_factor(), and Multifile().

Subfiles Multifile::_subfiles [private]
 

Definition at line 146 of file multifile.h.

Referenced by find_subfile(), flush(), get_num_subfiles(), has_directory(), and read_subfile().

ostream* Multifile::_write [private]
 

Definition at line 152 of file multifile.h.

Referenced by add_subfile(), flush(), get_subfile_compressed_length(), is_read_valid(), open_read(), open_write(), and read_subfile().

ofstream Multifile::_write_file [private]
 

Definition at line 161 of file multifile.h.

Referenced by open_read(), and open_read_write().


The documentation for this class was generated from the following files:
Generated on Fri May 2 00:52:29 2003 for Panda by doxygen1.3