# Multifile

from pandac.PandaModules import Multifile

Class : Multifile
Description : A file that contains a set of files.

## Inheritance:

Multifile: ReferenceCount
ReferenceCount: MemoryBase
MemoryBase:

## Methods of Multifile:

Multifile (Constructor)
addSubfile
close
compareSubfile
extractSubfile
extractSubfileTo
findSubfile
flush
getEncryptionFlag
getEncryptionPassword
getIndexEnd
getMagicNumber
getMultifileName
getNumSubfiles
getRecordTimestamp
getScaleFactor
getSubfileInternalLength
getSubfileInternalStart
getSubfileLength
getSubfileName
getSubfileTimestamp
getTimestamp
hasDirectory
isReadValid
isSubfileCompressed
isSubfileEncrypted
isWriteValid
ls
needsRepack
openRead
openReadSubfile
openReadWrite
openWrite
output
readSubfile
removeSubfile
repack
scanDirectory
setEncryptionFlag
setEncryptionPassword
setMultifileName
setRecordTimestamp
setScaleFactor
updateSubfile

## Methods of ReferenceCount:

getClassType
getRefCount
ref
testRefCountIntegrity
testRefCountNonzero
unref

Multifile Multifile::Multifile(void); A Multifile consists of the following elements: (1) A header. This is always the first n bytes of the Multifile, and contains a magic number to identify the file, as well as version numbers and any file-specific parameters. char[6] The string Multifile::_header, a magic number. int16 The file's major version number int16 The file's minor version number uint32 Scale factor. This scales all address references within the file. Normally 1, this may be set larger to support Multifiles larger than 4GB. uint32 An overall modification timestamp for the entire multifile. (2) Zero or more index entries, one for each subfile within the Multifile. These entries are of variable length. The first one of these immediately follows the header, and the first word of each index entry contains the address of the next index entry. A zero "next" address marks the end of the chain. These may appear at any point within the Multifile; they do not necessarily appear in sequential order at the beginning of the file (although they will after the file has been "packed"). uint32 The address of the next entry. 0 to mark the end. uint32 The address of this subfile's data record. uint32 The length in bytes of this subfile's data record. uint16 The Subfile::_flags member. [uint32] The original, uncompressed and unencrypted length of the subfile, if it is compressed or encrypted. This field is only present if one or both of the SF_compressed or SF_encrypted bits are set in _flags. uint32 A modification timestamp for the subfile. uint16 The length in bytes of the subfile's name. char[n] The subfile's name. (3) Zero or more data entries, one for each subfile. These may appear at any point within the Multifile; they do not necessarily follow each index entry, nor are they necessarily all grouped together at the end (although they will be all grouped together at the end after the file has been "packed"). These are just blocks of literal data. Description: Description: Don't try to copy Multifiles.

addSubfile string Multifile::add_subfile(string const &subfile_name, Filename const &filename, int compression_level); Description: 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(). If there already exists a subfile with the indicated name, it is replaced without examining its contents (but see also update_subfile). Returns the subfile name on success (it might have been modified slightly), or empty string on failure. Description: Adds a file from a stream 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(). Note that the istream must remain untouched and unused by any other code until flush() is called. At that time, the Multifile will read the entire contents of the istream from the current file position to the end of the file. Subsequently, the Multifile will *not* close or delete the istream. It is the caller's responsibility to ensure that the istream pointer does not destruct during the lifetime of the Multifile.

close void Multifile::close(void); Description: 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().

compareSubfile bool Multifile::compare_subfile(int index, Filename const &filename); Description: Performs a byte-for-byte comparison of the indicated file on disk with the nth subfile. Returns true if the files are equivalent, or false if they are different (or the file is missing).

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

extractSubfileTo bool Multifile::extract_subfile_to(int index, ostream &out); Description: Extracts the nth subfile to the indicated ostream.

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

flush bool Multifile::flush(void); Description: 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.

getEncryptionFlag bool Multifile::get_encryption_flag(void) const; Description: Returns the flag indicating whether subsequently-added subfiles should be encrypted before writing them to the multifile. See set_encryption_flag().

getEncryptionPassword string const &Multifile::get_encryption_password(void) const; Description: Returns the password that will be used to encrypt subfiles subsequently added to the multifile. See set_encryption_password().

getIndexEnd int Multifile::get_index_end(void) const; Description: Returns the first byte that is guaranteed to follow any index byte already written to disk in the Multifile. This number is largely meaningless in many cases, but if needs_repack() is false, and the file is flushed, this will indicate the number of bytes in the header + index. Everything at this byte position and later will be actual data.

getMagicNumber static string Multifile::get_magic_number(void); Description: Returns a string with the first n bytes written to a Multifile, to identify it as a Multifile.

getMultifileName Filename const &Multifile::get_multifile_name(void) const; Description: Returns the filename of the Multifile, if it is available.

getNumSubfiles int Multifile::get_num_subfiles(void) const; Description: Returns the number of subfiles within the Multifile. The subfiles may be accessed in alphabetical order by iterating through [0 .. get_num_subfiles()).

getRecordTimestamp bool Multifile::get_record_timestamp(void) const; Description: Returns the flag indicating whether timestamps should be recorded within the Multifile or not. See set_record_timestamp().

getScaleFactor unsigned int Multifile::get_scale_factor(void) const; Description: Returns the internal scale factor for this Multifile. See set_scale_factor().

getSubfileInternalLength unsigned int Multifile::get_subfile_internal_length(int index) const; Description: 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 encrypted (but noncompressed) subfiles, it may be slightly different, for noncompressed and nonencrypted subfiles, it will be equal.

getSubfileInternalStart int Multifile::get_subfile_internal_start(int index) const; Description: Returns the starting byte position within the Multifile at which the indicated subfile begins. This may be used, with get_subfile_internal_length(), for low-level access to the subfile, but usually it is better to use open_read_subfile() instead (which automatically decrypts and/or uncompresses the subfile data).

getSubfileLength unsigned int Multifile::get_subfile_length(int index) const; Description: 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.

getSubfileName string const &Multifile::get_subfile_name(int index) const; Description: Returns the name of the nth subfile.

getSubfileTimestamp unsigned int Multifile::get_subfile_timestamp(int index) const; Description: Returns the modification time of the nth subfile. If this is called on an older .mf file, which did not store individual timestamps in the file (or if get_record_timestamp() is false), this will return the modification time of the overall multifile.

getTimestamp unsigned int Multifile::get_timestamp(void) const; Description: Returns the modification timestamp of the overall Multifile. This indicates the most recent date at which subfiles were added or removed from the Multifile. Note that it is logically possible for an individual subfile to have a more recent timestamp than the overall timestamp.

hasDirectory bool Multifile::has_directory(string const &subfile_name) const; Description: 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/...".

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

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

isSubfileEncrypted bool Multifile::is_subfile_encrypted(int index) const; Description: Returns true if the indicated subfile has been encrypted when stored within the archive, false otherwise.

isWriteValid bool Multifile::is_write_valid(void) const; Description: 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.

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

needsRepack bool Multifile::needs_repack(void) const; Description: Returns true if the Multifile index is suboptimal and should be repacked. Call repack() to achieve this.

openRead bool Multifile::open_read(Filename const &multifile_name); Description: 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. Description: Opens an anonymous Multifile for reading using an istream. There must be seek functionality via seekg() and tellg() on the istream. If owns_pointer is true, then the Multifile assumes ownership of the stream pointer and will delete it when the multifile is closed, including if this function returns false.

openReadSubfile istream *Multifile::open_read_subfile(int index); Description: 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 pfstream 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.

openReadWrite bool Multifile::open_read_write(Filename const &multifile_name); Description: 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. Description: 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. If owns_pointer is true, then the Multifile assumes ownership of the stream pointer and will delete it when the multifile is closed, including if this function returns false.

openWrite bool Multifile::open_write(Filename const &multifile_name); Description: 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. Description: Opens an anonymous Multifile for writing using an ostream. There must be seek functionality via seekp() and tellp() on the pstream. If owns_pointer is true, then the Multifile assumes ownership of the stream pointer and will delete it when the multifile is closed, including if this function returns false.

output void Multifile::output(ostream &out) const; Description:

readSubfile string Multifile::read_subfile(int index); Description: Returns a string that contains the entire contents of the indicated subfile. Description: Fills a string with the entire contents of the indicated subfile. Description: Fills a pvector with the entire contents of the indicated subfile.

removeSubfile void Multifile::remove_subfile(int index); Description: 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().

repack bool Multifile::repack(void); Description: 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.

scanDirectory bool Multifile::scan_directory(vector< string > &contents, string const &subfile_name) const; Description: Considers subfile_name to be the name of a subdirectory within the Multifile, but not a file itself; fills 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.

setEncryptionFlag void Multifile::set_encryption_flag(bool flag); Description: Sets the flag indicating whether subsequently-added subfiles should be encrypted before writing them to the multifile. If true, subfiles will be encrypted; if false (the default), they will be written without encryption. When true, subfiles will be encrypted with the password specified by set_encryption_password(). It is possible to apply a different password to different files, but you must call flush() or repack() before changing these properties, and the resulting file can't be mounted via VFS.

setEncryptionPassword void Multifile::set_encryption_password(string const &password); Description: Specifies the password that will be used to encrypt subfiles subsequently added to the multifile, if the encryption flag is also set true (see set_encryption_flag()).

setMultifileName void Multifile::set_multifile_name(Filename const &multifile_name); Description: Replaces the filename of the Multifile. This is primarily used for documentation purposes only; changing this name does not open the indicated file. See open_read() or open_write() for that.

setRecordTimestamp void Multifile::set_record_timestamp(bool record_timestamp); Description: Sets the flag indicating whether timestamps should be recorded within the Multifile or not. The default is true, indicating the Multifile will record timestamps for the overall file and also for each subfile. If this is false, the Multifile will not record timestamps internally. In this case, the return value from get_timestamp() or get_subfile_timestamp() will be estimations. You may want to set this false to minimize the bitwise difference between independently-generated Multifiles.

setScaleFactor void Multifile::set_scale_factor(unsigned int scale_factor); Description: 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).

updateSubfile string Multifile::update_subfile(string const &subfile_name, Filename const &filename, int compression_level); Description: Adds a file on disk to the subfile. If a subfile already exists with the same name, its contents are compared byte-for-byte to the disk file, and it is replaced only if it is different; otherwise, the multifile is left unchanged.

getClassType static TypeHandle ReferenceCount::get_class_type(void); Undocumented function.

getRefCount int ReferenceCount::get_ref_count(void) const; Description: Returns the current reference count.

ref void ReferenceCount::ref(void) const; Description: Explicitly increments the reference count. User code should avoid using ref() and unref() directly, which can result in missed reference counts. Instead, let a PointerTo object manage the reference counting automatically. This function is const, even though it changes the object, because generally fiddling with an object's reference count isn't considered part of fiddling with the object. An object might be const in other ways, but we still need to accurately count the number of references to it.

testRefCountIntegrity bool ReferenceCount::test_ref_count_integrity(void) const; Description: Does some easy checks to make sure that the reference count isn't completely bogus. Returns true if ok, false otherwise.

testRefCountNonzero bool ReferenceCount::test_ref_count_nonzero(void) const; Description: Does some easy checks to make sure that the reference count isn't zero, or completely bogus. Returns true if ok, false otherwise.

unref bool ReferenceCount::unref(void) const; Description: Explicitly decrements the reference count. Note that the object will not be implicitly deleted by unref() simply because the reference count drops to zero. (Having a member function delete itself is problematic; plus, we don't have a virtual destructor anyway.) However, see the helper function unref_delete(). User code should avoid using ref() and unref() directly, which can result in missed reference counts. Instead, let a PointerTo object manage the reference counting automatically. This function is const, even though it changes the object, because generally fiddling with an object's reference count isn't considered part of fiddling with the object. An object might be const in other ways, but we still need to accurately count the number of references to it. The return value is true if the new reference count is nonzero, false if it is zero.