mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 19:08:55 -04:00
initial virtual file system
This commit is contained in:
parent
410a8f423a
commit
255bcd1299
@ -123,13 +123,13 @@ run() {
|
|||||||
|
|
||||||
_subfile_length = _multifile.get_subfile_length(_subfile_index);
|
_subfile_length = _multifile.get_subfile_length(_subfile_index);
|
||||||
_subfile_pos = 0;
|
_subfile_pos = 0;
|
||||||
_read = &_multifile.open_read_subfile(_subfile_index);
|
_read = _multifile.open_read_subfile(_subfile_index);
|
||||||
|
|
||||||
} else if (_subfile_pos >= _subfile_length) {
|
} else if (_subfile_pos >= _subfile_length) {
|
||||||
// Time to close this subfile.
|
// Time to close this subfile.
|
||||||
_multifile.close_subfile();
|
delete _read;
|
||||||
_write.close();
|
|
||||||
_read = (istream *)NULL;
|
_read = (istream *)NULL;
|
||||||
|
_write.close();
|
||||||
_subfile_index++;
|
_subfile_index++;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -195,7 +195,10 @@ cleanup() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_read != (istream *)NULL) {
|
||||||
|
delete _read;
|
||||||
|
_read = (istream *)NULL;
|
||||||
|
}
|
||||||
_multifile.close();
|
_multifile.close();
|
||||||
_write.close();
|
_write.close();
|
||||||
_read = (istream *)NULL;
|
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,17 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Multifile::get_multifile_name
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the filename of the Multifile, if it is
|
||||||
|
// available.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const Filename &Multifile::
|
||||||
|
get_multifile_name() const {
|
||||||
|
return _multifile_name;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Multifile::is_read_valid
|
// Function: Multifile::is_read_valid
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -26,8 +37,7 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE bool Multifile::
|
INLINE bool Multifile::
|
||||||
is_read_valid() const {
|
is_read_valid() const {
|
||||||
return (_read != (istream *)NULL && !_read->fail() &&
|
return (_read != (istream *)NULL && !_read->fail());
|
||||||
_open_subfile == (Subfile *)NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -39,8 +49,7 @@ is_read_valid() const {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE bool Multifile::
|
INLINE bool Multifile::
|
||||||
is_write_valid() const {
|
is_write_valid() const {
|
||||||
return (_write != (ostream *)NULL && !_write->fail() &&
|
return (_write != (ostream *)NULL && !_write->fail());
|
||||||
_open_subfile == (Subfile *)NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -51,39 +60,7 @@ is_write_valid() const {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE bool Multifile::
|
INLINE bool Multifile::
|
||||||
needs_repack() const {
|
needs_repack() const {
|
||||||
return _needs_repack;
|
return _needs_repack || (_scale_factor != _new_scale_factor);
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: Multifile::set_scale_factor
|
|
||||||
// Access: Published
|
|
||||||
// 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 forces an immediate repack() operation.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
INLINE void Multifile::
|
|
||||||
set_scale_factor(size_t scale_factor) {
|
|
||||||
nassertv(scale_factor != (size_t)0);
|
|
||||||
if (_scale_factor != scale_factor) {
|
|
||||||
_scale_factor = scale_factor;
|
|
||||||
if (_next_index != (streampos)0) {
|
|
||||||
repack();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -94,7 +71,7 @@ set_scale_factor(size_t scale_factor) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE size_t Multifile::
|
INLINE size_t Multifile::
|
||||||
get_scale_factor() const {
|
get_scale_factor() const {
|
||||||
return _scale_factor;
|
return _new_scale_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -84,9 +84,9 @@ Multifile() {
|
|||||||
_last_index = 0;
|
_last_index = 0;
|
||||||
_needs_repack = false;
|
_needs_repack = false;
|
||||||
_scale_factor = 1;
|
_scale_factor = 1;
|
||||||
|
_new_scale_factor = 1;
|
||||||
_file_major_ver = 0;
|
_file_major_ver = 0;
|
||||||
_file_minor_ver = 0;
|
_file_minor_ver = 0;
|
||||||
_open_subfile = (Subfile *)NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -99,6 +99,26 @@ Multifile::
|
|||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Multifile::Copy Constructor
|
||||||
|
// Access: Private
|
||||||
|
// Description: Don't try to copy Multifiles.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Multifile::
|
||||||
|
Multifile(const Multifile ©) {
|
||||||
|
nassertv(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Multifile::Copy Assignment Operator
|
||||||
|
// Access: Private
|
||||||
|
// Description: Don't try to copy Multifiles.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void Multifile::
|
||||||
|
operator = (const Multifile ©) {
|
||||||
|
nassertv(false);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Multifile::open_read
|
// Function: Multifile::open_read
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -192,14 +212,21 @@ open_read_write(const Filename &multifile_name) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void Multifile::
|
void Multifile::
|
||||||
close() {
|
close() {
|
||||||
close_subfile();
|
if (_new_scale_factor != _scale_factor) {
|
||||||
|
// If we have changed the scale factor recently, we need to force
|
||||||
|
// a repack.
|
||||||
|
repack();
|
||||||
|
} else {
|
||||||
flush();
|
flush();
|
||||||
|
}
|
||||||
|
|
||||||
_read = (istream *)NULL;
|
_read = (istream *)NULL;
|
||||||
_write = (ostream *)NULL;
|
_write = (ostream *)NULL;
|
||||||
_next_index = 0;
|
_next_index = 0;
|
||||||
_last_index = 0;
|
_last_index = 0;
|
||||||
_needs_repack = false;
|
_needs_repack = false;
|
||||||
_scale_factor = 1;
|
_scale_factor = 1;
|
||||||
|
_new_scale_factor = 1;
|
||||||
_file_major_ver = 0;
|
_file_major_ver = 0;
|
||||||
_file_minor_ver = 0;
|
_file_minor_ver = 0;
|
||||||
|
|
||||||
@ -211,6 +238,49 @@ close() {
|
|||||||
clear_subfiles();
|
clear_subfiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Multifile::set_scale_factor
|
||||||
|
// Access: Published
|
||||||
|
// 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).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void Multifile::
|
||||||
|
set_scale_factor(size_t scale_factor) {
|
||||||
|
nassertv(is_write_valid());
|
||||||
|
nassertv(scale_factor != (size_t)0);
|
||||||
|
|
||||||
|
if (_next_index == (streampos)0) {
|
||||||
|
// If it's a brand new Multifile, we can go ahead and set it
|
||||||
|
// immediately.
|
||||||
|
_scale_factor = scale_factor;
|
||||||
|
} else {
|
||||||
|
// Otherwise, we'd better have read access so we can repack it
|
||||||
|
// later.
|
||||||
|
nassertv(is_read_valid());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setting the _new_scale_factor different from the _scale_factor
|
||||||
|
// will force a repack operation on close.
|
||||||
|
_new_scale_factor = scale_factor;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Multifile::add_subfile
|
// Function: Multifile::add_subfile
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -378,6 +448,12 @@ flush() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool Multifile::
|
bool Multifile::
|
||||||
repack() {
|
repack() {
|
||||||
|
if (_next_index == (streampos)0) {
|
||||||
|
// If the Multifile hasn't yet been written, this is really just a
|
||||||
|
// flush operation.
|
||||||
|
return flush();
|
||||||
|
}
|
||||||
|
|
||||||
nassertr(is_write_valid() && is_read_valid(), false);
|
nassertr(is_write_valid() && is_read_valid(), false);
|
||||||
nassertr(!_multifile_name.empty(), false);
|
nassertr(!_multifile_name.empty(), false);
|
||||||
|
|
||||||
@ -407,6 +483,7 @@ repack() {
|
|||||||
copy(_subfiles.begin(), _subfiles.end(), back_inserter(_new_subfiles));
|
copy(_subfiles.begin(), _subfiles.end(), back_inserter(_new_subfiles));
|
||||||
_next_index = 0;
|
_next_index = 0;
|
||||||
_last_index = 0;
|
_last_index = 0;
|
||||||
|
_scale_factor = _new_scale_factor;
|
||||||
|
|
||||||
// And we write our contents to our new temporary file.
|
// And we write our contents to our new temporary file.
|
||||||
_write = &temp;
|
_write = &temp;
|
||||||
@ -535,14 +612,14 @@ read_subfile(int index, Datagram &data) {
|
|||||||
nassertv(index >= 0 && index < (int)_subfiles.size());
|
nassertv(index >= 0 && index < (int)_subfiles.size());
|
||||||
data.clear();
|
data.clear();
|
||||||
|
|
||||||
istream &in = open_read_subfile(index);
|
istream *in = open_read_subfile(index);
|
||||||
int byte = in.get();
|
int byte = in->get();
|
||||||
while (!in.eof() && !in.fail()) {
|
while (!in->eof() && !in->fail()) {
|
||||||
data.add_int8(byte);
|
data.add_int8(byte);
|
||||||
byte = in.get();
|
byte = in->get();
|
||||||
}
|
}
|
||||||
bool failed = in.fail();
|
bool failed = in->fail();
|
||||||
close_subfile();
|
delete in;
|
||||||
nassertv(!failed);
|
nassertv(!failed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,6 +647,31 @@ extract_subfile(int index, const Filename &filename) {
|
|||||||
return extract_subfile_to(index, out);
|
return extract_subfile_to(index, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Multifile::output
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void Multifile::
|
||||||
|
output(ostream &out) const {
|
||||||
|
out << "Multifile " << _multifile_name << ", " << get_num_subfiles()
|
||||||
|
<< " subfiles.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Multifile::ls
|
||||||
|
// Access: Published
|
||||||
|
// Description: Shows a list of all subfiles within the Multifile.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void Multifile::
|
||||||
|
ls(ostream &out) const {
|
||||||
|
int num_subfiles = get_num_subfiles();
|
||||||
|
for (int i = 0; i < num_subfiles; i++) {
|
||||||
|
string subfile_name = get_subfile_name(i);
|
||||||
|
out << subfile_name << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Multifile::open_read
|
// Function: Multifile::open_read
|
||||||
// Access: Public
|
// Access: Public
|
||||||
@ -662,16 +764,16 @@ extract_subfile_to(int index, ostream &out) {
|
|||||||
nassertr(is_read_valid(), false);
|
nassertr(is_read_valid(), false);
|
||||||
nassertr(index >= 0 && index < (int)_subfiles.size(), false);
|
nassertr(index >= 0 && index < (int)_subfiles.size(), false);
|
||||||
|
|
||||||
istream &in = open_read_subfile(index);
|
istream *in = open_read_subfile(index);
|
||||||
|
|
||||||
int byte = in.get();
|
int byte = in->get();
|
||||||
while (!in.fail() && !in.eof()) {
|
while (!in->fail() && !in->eof()) {
|
||||||
out.put(byte);
|
out.put(byte);
|
||||||
byte = in.get();
|
byte = in->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool failed = (in.fail() && !in.eof());
|
bool failed = (in->fail() && !in->eof());
|
||||||
close_subfile();
|
delete in;
|
||||||
nassertr(!failed, false);
|
nassertr(!failed, false);
|
||||||
|
|
||||||
return (!out.fail());
|
return (!out.fail());
|
||||||
@ -682,64 +784,47 @@ extract_subfile_to(int index, ostream &out) {
|
|||||||
// Access: Public
|
// Access: Public
|
||||||
// Description: Returns an istream that may be used to read the
|
// Description: Returns an istream that may be used to read the
|
||||||
// indicated subfile. You may seek() within this
|
// indicated subfile. You may seek() within this
|
||||||
// istream to your heart's content; even though it is
|
// istream to your heart's content; even though it will
|
||||||
// probably a reference to the already-opened fstream of
|
// be a reference to the already-opened fstream of the
|
||||||
// the Multifile itself, byte 0 appears to be the
|
// Multifile itself, byte 0 appears to be the beginning
|
||||||
// beginning of the subfile and EOF appears to be the
|
// of the subfile and EOF appears to be the end of the
|
||||||
// end of the subfile.
|
// subfile.
|
||||||
//
|
//
|
||||||
// It is not valid to perform any additional operations
|
// The returned istream will have been allocated via
|
||||||
// on this Multifile until close_subfile() has
|
// new; you should delete it when you are finished
|
||||||
// subsequently been called.
|
// 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 never be NULL. If there is a
|
||||||
|
// problem, an unopened fstream is returned.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
istream &Multifile::
|
istream *Multifile::
|
||||||
open_read_subfile(int index) {
|
open_read_subfile(int index) {
|
||||||
#ifndef NDEBUG
|
nassertr(is_read_valid(), new fstream);
|
||||||
static ifstream empty_stream;
|
nassertr(index >= 0 && index < (int)_subfiles.size(), new fstream);
|
||||||
nassertr(_open_subfile == (Subfile *)NULL, empty_stream);
|
Subfile *subfile = _subfiles[index];
|
||||||
nassertr(is_read_valid(), empty_stream);
|
|
||||||
nassertr(index >= 0 && index < (int)_subfiles.size(), empty_stream);
|
|
||||||
#endif
|
|
||||||
_open_subfile = _subfiles[index];
|
|
||||||
|
|
||||||
if (_open_subfile->_source != (istream *)NULL) {
|
if (subfile->_source != (istream *)NULL ||
|
||||||
// The subfile has not yet been incorporated, and it is defined
|
!subfile->_source_filename.empty()) {
|
||||||
// with an istream; return the istream directly.
|
// The subfile has not yet been copied into the physical
|
||||||
_open_subfile->_source->seekg(0);
|
// Multifile. Force a flush operation to incorporate it.
|
||||||
return *_open_subfile->_source;
|
flush();
|
||||||
|
|
||||||
|
// That shouldn't change the subfile index or delete the subfile
|
||||||
|
// pointer.
|
||||||
|
nassertr(subfile == _subfiles[index], new fstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_open_subfile->_source_filename.empty()) {
|
// Return an ISubStream object that references into the open
|
||||||
// The subfile has not yet been incorporated, and it is defined
|
// Multifile istream.
|
||||||
// with a filename; open the filename and return that.
|
nassertr(subfile->_data_start != (streampos)0, new fstream);
|
||||||
_open_subfile->_source_filename.open_read(_subfile_fstream);
|
ISubStream *stream = new ISubStream;
|
||||||
return _subfile_fstream;
|
stream->open(_read, subfile->_data_start,
|
||||||
}
|
subfile->_data_start + (streampos)subfile->_data_length);
|
||||||
|
return stream;
|
||||||
// The subfile has been incorporated; return an ISubStream object
|
|
||||||
// that references into the open Multifile istream.
|
|
||||||
nassertr(_open_subfile->_data_start != (streampos)0, empty_stream);
|
|
||||||
_subfile_substream.open(_read, _open_subfile->_data_start,
|
|
||||||
_open_subfile->_data_start + (streampos)_open_subfile->_data_length);
|
|
||||||
return _subfile_substream;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: Multifile::close_subfile
|
|
||||||
// Access: Public
|
|
||||||
// Description: "Closes" the istream that was returned via a previous
|
|
||||||
// call to open_read_subfile(), and makes other
|
|
||||||
// operations on the Multifile valid once more.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void Multifile::
|
|
||||||
close_subfile() {
|
|
||||||
if (_open_subfile != (Subfile *)NULL &&
|
|
||||||
_open_subfile->_source != (istream *)NULL) {
|
|
||||||
_open_subfile->_source->seekg(0);
|
|
||||||
}
|
|
||||||
_open_subfile = (Subfile *)NULL;
|
|
||||||
_subfile_fstream.close();
|
|
||||||
_subfile_substream.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -850,6 +935,7 @@ read_index() {
|
|||||||
_file_major_ver = dgi.get_int16();
|
_file_major_ver = dgi.get_int16();
|
||||||
_file_minor_ver = dgi.get_int16();
|
_file_minor_ver = dgi.get_int16();
|
||||||
_scale_factor = dgi.get_uint32();
|
_scale_factor = dgi.get_uint32();
|
||||||
|
_new_scale_factor = _scale_factor;
|
||||||
|
|
||||||
if (_file_major_ver != _current_major_ver ||
|
if (_file_major_ver != _current_major_ver ||
|
||||||
(_file_major_ver == _current_major_ver &&
|
(_file_major_ver == _current_major_ver &&
|
||||||
|
@ -38,16 +38,23 @@ PUBLISHED:
|
|||||||
Multifile();
|
Multifile();
|
||||||
~Multifile();
|
~Multifile();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Multifile(const Multifile ©);
|
||||||
|
void operator = (const Multifile ©);
|
||||||
|
|
||||||
|
PUBLISHED:
|
||||||
bool open_read(const Filename &multifile_name);
|
bool open_read(const Filename &multifile_name);
|
||||||
bool open_write(const Filename &multifile_name);
|
bool open_write(const Filename &multifile_name);
|
||||||
bool open_read_write(const Filename &multifile_name);
|
bool open_read_write(const Filename &multifile_name);
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
|
INLINE const Filename &get_multifile_name() const;
|
||||||
|
|
||||||
INLINE bool is_read_valid() const;
|
INLINE bool is_read_valid() const;
|
||||||
INLINE bool is_write_valid() const;
|
INLINE bool is_write_valid() const;
|
||||||
INLINE bool needs_repack() const;
|
INLINE bool needs_repack() const;
|
||||||
|
|
||||||
INLINE void set_scale_factor(size_t scale_factor);
|
void set_scale_factor(size_t scale_factor);
|
||||||
INLINE size_t get_scale_factor() const;
|
INLINE size_t get_scale_factor() const;
|
||||||
|
|
||||||
bool add_subfile(const string &subfile_name, const Filename &filename);
|
bool add_subfile(const string &subfile_name, const Filename &filename);
|
||||||
@ -63,6 +70,9 @@ PUBLISHED:
|
|||||||
void read_subfile(int index, Datagram &datagram);
|
void read_subfile(int index, Datagram &datagram);
|
||||||
bool extract_subfile(int index, const Filename &filename);
|
bool extract_subfile(int index, const Filename &filename);
|
||||||
|
|
||||||
|
void output(ostream &out) const;
|
||||||
|
void ls(ostream &out = cout) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Special interfaces to work with iostreams, not necessarily files.
|
// Special interfaces to work with iostreams, not necessarily files.
|
||||||
bool open_read(istream *multifile_stream);
|
bool open_read(istream *multifile_stream);
|
||||||
@ -71,8 +81,7 @@ public:
|
|||||||
bool add_subfile(const string &subfile_name, istream *subfile_data);
|
bool add_subfile(const string &subfile_name, istream *subfile_data);
|
||||||
|
|
||||||
bool extract_subfile_to(int index, ostream &out);
|
bool extract_subfile_to(int index, ostream &out);
|
||||||
istream &open_read_subfile(int index);
|
istream *open_read_subfile(int index);
|
||||||
void close_subfile();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum SubfileFlags {
|
enum SubfileFlags {
|
||||||
@ -129,6 +138,7 @@ private:
|
|||||||
|
|
||||||
bool _needs_repack;
|
bool _needs_repack;
|
||||||
size_t _scale_factor;
|
size_t _scale_factor;
|
||||||
|
size_t _new_scale_factor;
|
||||||
|
|
||||||
ifstream _read_file;
|
ifstream _read_file;
|
||||||
ofstream _write_file;
|
ofstream _write_file;
|
||||||
@ -138,11 +148,6 @@ private:
|
|||||||
int _file_major_ver;
|
int _file_major_ver;
|
||||||
int _file_minor_ver;
|
int _file_minor_ver;
|
||||||
|
|
||||||
// These are used to open a subfile for reading.
|
|
||||||
Subfile *_open_subfile;
|
|
||||||
ifstream _subfile_fstream;
|
|
||||||
ISubStream _subfile_substream;
|
|
||||||
|
|
||||||
static const char _header[];
|
static const char _header[];
|
||||||
static const size_t _header_size;
|
static const size_t _header_size;
|
||||||
static const int _current_major_ver;
|
static const int _current_major_ver;
|
||||||
|
@ -49,6 +49,7 @@ SubStreamBuf() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
SubStreamBuf::
|
SubStreamBuf::
|
||||||
~SubStreamBuf() {
|
~SubStreamBuf() {
|
||||||
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -46,6 +46,12 @@
|
|||||||
typedWritableReferenceCount.h updateSeq.I updateSeq.h \
|
typedWritableReferenceCount.h updateSeq.I updateSeq.h \
|
||||||
vector_double.h vector_float.h vector_typedWritable.h \
|
vector_double.h vector_float.h vector_typedWritable.h \
|
||||||
vector_ushort.h vector_writable.h \
|
vector_ushort.h vector_writable.h \
|
||||||
|
virtualFileComposite.h virtualFileComposite.I virtualFile.h \
|
||||||
|
virtualFile.I virtualFileList.I virtualFileList.h virtualFileMount.h \
|
||||||
|
virtualFileMount.I virtualFileMountMultifile.h \
|
||||||
|
virtualFileMountMultifile.I virtualFileMountSystem.h \
|
||||||
|
virtualFileMountSystem.I virtualFileSimple.h virtualFileSimple.I \
|
||||||
|
virtualFileSystem.h virtualFileSystem.I \
|
||||||
writableConfigurable.h \
|
writableConfigurable.h \
|
||||||
writableParam.I writableParam.h
|
writableParam.I writableParam.h
|
||||||
|
|
||||||
@ -75,6 +81,10 @@
|
|||||||
vector_double.cxx vector_float.cxx \
|
vector_double.cxx vector_float.cxx \
|
||||||
vector_typedWritable.cxx \
|
vector_typedWritable.cxx \
|
||||||
vector_ushort.cxx vector_writable.cxx \
|
vector_ushort.cxx vector_writable.cxx \
|
||||||
|
virtualFileComposite.cxx virtualFile.cxx virtualFileList.cxx \
|
||||||
|
virtualFileMount.cxx \
|
||||||
|
virtualFileMountMultifile.cxx virtualFileMountSystem.cxx \
|
||||||
|
virtualFileSimple.cxx virtualFileSystem.cxx \
|
||||||
writableConfigurable.cxx writableParam.cxx
|
writableConfigurable.cxx writableParam.cxx
|
||||||
|
|
||||||
#define INSTALL_HEADERS \
|
#define INSTALL_HEADERS \
|
||||||
@ -113,6 +123,12 @@
|
|||||||
typedWritableReferenceCount.h updateSeq.I updateSeq.h \
|
typedWritableReferenceCount.h updateSeq.I updateSeq.h \
|
||||||
vector_double.h vector_float.h vector_typedWritable.h \
|
vector_double.h vector_float.h vector_typedWritable.h \
|
||||||
vector_ushort.h vector_writable.h \
|
vector_ushort.h vector_writable.h \
|
||||||
|
virtualFileComposite.h virtualFileComposite.I virtualFile.h \
|
||||||
|
virtualFile.I virtualFileList.I virtualFileList.h virtualFileMount.h \
|
||||||
|
virtualFileMount.I virtualFileMountMultifile.h \
|
||||||
|
virtualFileMountMultifile.I virtualFileMountSystem.h \
|
||||||
|
virtualFileMountSystem.I virtualFileSimple.h virtualFileSimple.I \
|
||||||
|
virtualFileSystem.h virtualFileSystem.I \
|
||||||
writableConfigurable.h writableParam.I \
|
writableConfigurable.h writableParam.I \
|
||||||
writableParam.h
|
writableParam.h
|
||||||
|
|
||||||
|
@ -30,6 +30,12 @@
|
|||||||
#include "datagram.h"
|
#include "datagram.h"
|
||||||
#include "typedWritable.h"
|
#include "typedWritable.h"
|
||||||
#include "typedWritableReferenceCount.h"
|
#include "typedWritableReferenceCount.h"
|
||||||
|
#include "virtualFileComposite.h"
|
||||||
|
#include "virtualFile.h"
|
||||||
|
#include "virtualFileMount.h"
|
||||||
|
#include "virtualFileMountMultifile.h"
|
||||||
|
#include "virtualFileMountSystem.h"
|
||||||
|
#include "virtualFileSimple.h"
|
||||||
#include "writableParam.h"
|
#include "writableParam.h"
|
||||||
#include "bamReaderParam.h"
|
#include "bamReaderParam.h"
|
||||||
#include "writableConfigurable.h"
|
#include "writableConfigurable.h"
|
||||||
@ -57,6 +63,12 @@ ConfigureFn(config_util) {
|
|||||||
WritableParam::init_type();
|
WritableParam::init_type();
|
||||||
BamReaderParam::init_type();
|
BamReaderParam::init_type();
|
||||||
TypedWritableReferenceCount::init_type();
|
TypedWritableReferenceCount::init_type();
|
||||||
|
VirtualFileComposite::init_type();
|
||||||
|
VirtualFile::init_type();
|
||||||
|
VirtualFileMount::init_type();
|
||||||
|
VirtualFileMountMultifile::init_type();
|
||||||
|
VirtualFileMountSystem::init_type();
|
||||||
|
VirtualFileSimple::init_type();
|
||||||
WritableConfigurable::init_type();
|
WritableConfigurable::init_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,14 @@
|
|||||||
#include "vector_typedWritable.cxx"
|
#include "vector_typedWritable.cxx"
|
||||||
#include "vector_ushort.cxx"
|
#include "vector_ushort.cxx"
|
||||||
#include "vector_writable.cxx"
|
#include "vector_writable.cxx"
|
||||||
|
#include "virtualFile.cxx"
|
||||||
|
#include "virtualFileComposite.cxx"
|
||||||
|
#include "virtualFileList.cxx"
|
||||||
|
#include "virtualFileMount.cxx"
|
||||||
|
#include "virtualFileMountMultifile.cxx"
|
||||||
|
#include "virtualFileMountSystem.cxx"
|
||||||
|
#include "virtualFileSimple.cxx"
|
||||||
|
#include "virtualFileSystem.cxx"
|
||||||
#include "writableConfigurable.cxx"
|
#include "writableConfigurable.cxx"
|
||||||
#include "writableParam.cxx"
|
#include "writableParam.cxx"
|
||||||
|
|
||||||
|
35
panda/src/putil/virtualFile.I
Normal file
35
panda/src/putil/virtualFile.I
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Filename: virtualFile.I
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFile::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE VirtualFile::
|
||||||
|
VirtualFile() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
INLINE ostream &
|
||||||
|
operator << (ostream &out, const VirtualFile &file) {
|
||||||
|
file.output(out);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
233
panda/src/putil/virtualFile.cxx
Normal file
233
panda/src/putil/virtualFile.cxx
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
// Filename: virtualFile.cxx
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "virtualFile.h"
|
||||||
|
#include "virtualFileSystem.h"
|
||||||
|
#include "virtualFileList.h"
|
||||||
|
#include "config_util.h"
|
||||||
|
|
||||||
|
TypeHandle VirtualFile::_type_handle;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFile::is_directory
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description: Returns true if this file represents a directory (and
|
||||||
|
// scan_directory() may be called), false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFile::
|
||||||
|
is_directory() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFile::is_regular_file
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description: Returns true if this file represents a regular file
|
||||||
|
// (and read_file() may be called), false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFile::
|
||||||
|
is_regular_file() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFile::read_file
|
||||||
|
// Access: Published
|
||||||
|
// Description: Fills up the indicated Datagram with the contents of
|
||||||
|
// the file, if it is a regular file. Returns true on
|
||||||
|
// success, false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFile::
|
||||||
|
read_file(Datagram &data) const {
|
||||||
|
data.clear();
|
||||||
|
|
||||||
|
istream *in = open_read_file();
|
||||||
|
if (in == (istream *)NULL) {
|
||||||
|
util_cat.info()
|
||||||
|
<< "Unable to read " << get_filename() << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int byte = in->get();
|
||||||
|
while (!in->eof() && !in->fail()) {
|
||||||
|
data.add_int8(byte);
|
||||||
|
byte = in->get();
|
||||||
|
}
|
||||||
|
bool failed = in->fail();
|
||||||
|
delete in;
|
||||||
|
|
||||||
|
if (failed) {
|
||||||
|
util_cat.info()
|
||||||
|
<< "Error while reading " << get_filename() << "\n";
|
||||||
|
}
|
||||||
|
return failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFile::open_read_file
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description: Opens the file for reading. Returns a newly
|
||||||
|
// allocated istream on success (which you should
|
||||||
|
// eventually delete when you are done reading).
|
||||||
|
// Returns NULL on failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
istream *VirtualFile::
|
||||||
|
open_read_file() const {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFile::scan_directory
|
||||||
|
// Access: Published
|
||||||
|
// Description: If the file represents a directory (that is,
|
||||||
|
// is_directory() returns true), this returns the list
|
||||||
|
// of files within the directory at the current time.
|
||||||
|
// Returns NULL if the file is not a directory or if the
|
||||||
|
// directory cannot be read.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PT(VirtualFileList) VirtualFile::
|
||||||
|
scan_directory() const {
|
||||||
|
// First, we have to make sure there aren't any mount points attached
|
||||||
|
// under this directory. These will override any local filenames.
|
||||||
|
VirtualFileSystem *file_system = get_file_system();
|
||||||
|
Filename this_filename = get_filename();
|
||||||
|
vector_string mount_points_flat;
|
||||||
|
file_system->scan_mount_points(mount_points_flat, this_filename);
|
||||||
|
|
||||||
|
// Copy the set of nested mount points to a sorted list so we can
|
||||||
|
// search it quickly.
|
||||||
|
ov_set<string> mount_points;
|
||||||
|
copy(mount_points_flat.begin(), mount_points_flat.end(),
|
||||||
|
back_inserter(mount_points));
|
||||||
|
mount_points.sort();
|
||||||
|
|
||||||
|
|
||||||
|
PT(VirtualFileList) file_list = new VirtualFileList;
|
||||||
|
|
||||||
|
// Each of those mount points maps to a directory root or something
|
||||||
|
// from the file system.
|
||||||
|
ov_set<string>::const_iterator mi;
|
||||||
|
for (mi = mount_points.begin(); mi != mount_points.end(); ++mi) {
|
||||||
|
const string &basename = (*mi);
|
||||||
|
Filename filename(this_filename, basename);
|
||||||
|
PT(VirtualFile) file = file_system->get_file(filename);
|
||||||
|
file_list->add_file(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, get the actual local files in this directory.
|
||||||
|
vector_string names;
|
||||||
|
if (!scan_local_directory(file_list, mount_points)) {
|
||||||
|
// Not a directory, or unable to read directory.
|
||||||
|
if (file_list->get_num_files() == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We couldn't read the physical directory, but we do have some
|
||||||
|
// mounted files to return.
|
||||||
|
return file_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
return file_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFile::output
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void VirtualFile::
|
||||||
|
output(ostream &out) const {
|
||||||
|
out << get_filename();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFile::ls
|
||||||
|
// Access: Published
|
||||||
|
// Description: If the file represents a directory, lists its
|
||||||
|
// contents.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void VirtualFile::
|
||||||
|
ls(ostream &out) const {
|
||||||
|
CPT(VirtualFileList) contents = scan_directory();
|
||||||
|
if (contents == NULL) {
|
||||||
|
if (!is_directory()) {
|
||||||
|
out << get_filename() << " is not a directory.\n";
|
||||||
|
} else {
|
||||||
|
out << get_filename() << " cannot be read.\n";
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int num_files = contents->get_num_files();
|
||||||
|
for (int i = 0; i < num_files; i++) {
|
||||||
|
VirtualFile *file = contents->get_file(i);
|
||||||
|
out << file->get_filename().get_basename() << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFile::ls_all
|
||||||
|
// Access: Published
|
||||||
|
// Description: If the file represents a directory, recursively lists
|
||||||
|
// its contents and those of all subdirectories.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void VirtualFile::
|
||||||
|
ls_all(ostream &out) const {
|
||||||
|
if (!is_directory()) {
|
||||||
|
out << get_filename() << " is not a directory.\n";
|
||||||
|
} else {
|
||||||
|
r_ls_all(out, get_filename());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFile::scan_local_directory
|
||||||
|
// Access: Protected, Virtual
|
||||||
|
// Description: Fills file_list up with the list of files that are
|
||||||
|
// within this directory, excluding those whose
|
||||||
|
// basenames are listed in mount_points. Returns true
|
||||||
|
// if successful, false if the file is not a directory
|
||||||
|
// or the directory cannot be read.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFile::
|
||||||
|
scan_local_directory(VirtualFileList *, const ov_set<string> &) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFile::r_ls_all
|
||||||
|
// Access: Private
|
||||||
|
// Description: The recursive implementation of ls_all().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void VirtualFile::
|
||||||
|
r_ls_all(ostream &out, const Filename &root) const {
|
||||||
|
CPT(VirtualFileList) contents = scan_directory();
|
||||||
|
if (contents == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int num_files = contents->get_num_files();
|
||||||
|
for (int i = 0; i < num_files; i++) {
|
||||||
|
VirtualFile *file = contents->get_file(i);
|
||||||
|
Filename filename = file->get_filename();
|
||||||
|
filename.make_relative_to(root);
|
||||||
|
out << filename << "\n";
|
||||||
|
if (file->is_directory()) {
|
||||||
|
file->r_ls_all(out, root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
90
panda/src/putil/virtualFile.h
Normal file
90
panda/src/putil/virtualFile.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
// Filename: virtualFile.h
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef VIRTUALFILE_H
|
||||||
|
#define VIRTUALFILE_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
#include "filename.h"
|
||||||
|
#include "pointerTo.h"
|
||||||
|
#include "typedReferenceCount.h"
|
||||||
|
#include "ordered_vector.h"
|
||||||
|
|
||||||
|
class VirtualFileMount;
|
||||||
|
class VirtualFileList;
|
||||||
|
class VirtualFileSystem;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : VirtualFile
|
||||||
|
// Description : The abstract base class for a file or directory
|
||||||
|
// within the VirtualFileSystem.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA VirtualFile : public TypedReferenceCount {
|
||||||
|
public:
|
||||||
|
INLINE VirtualFile();
|
||||||
|
|
||||||
|
PUBLISHED:
|
||||||
|
virtual VirtualFileSystem *get_file_system() const=0;
|
||||||
|
virtual Filename get_filename() const=0;
|
||||||
|
|
||||||
|
virtual bool is_directory() const;
|
||||||
|
virtual bool is_regular_file() const;
|
||||||
|
|
||||||
|
bool read_file(Datagram &data) const;
|
||||||
|
virtual istream *open_read_file() const;
|
||||||
|
|
||||||
|
PT(VirtualFileList) scan_directory() const;
|
||||||
|
|
||||||
|
void output(ostream &out) const;
|
||||||
|
void ls(ostream &out = cout) const;
|
||||||
|
void ls_all(ostream &out = cout) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool scan_local_directory(VirtualFileList *file_list,
|
||||||
|
const ov_set<string> &mount_points) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void r_ls_all(ostream &out, const Filename &root) const;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual TypeHandle get_type() const {
|
||||||
|
return get_class_type();
|
||||||
|
}
|
||||||
|
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||||
|
static TypeHandle get_class_type() {
|
||||||
|
return _type_handle;
|
||||||
|
}
|
||||||
|
static void init_type() {
|
||||||
|
TypedReferenceCount::init_type();
|
||||||
|
register_type(_type_handle, "VirtualFile",
|
||||||
|
TypedReferenceCount::get_class_type());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static TypeHandle _type_handle;
|
||||||
|
|
||||||
|
friend class VirtualFileComposite;
|
||||||
|
};
|
||||||
|
|
||||||
|
INLINE ostream &operator << (ostream &out, const VirtualFile &file);
|
||||||
|
|
||||||
|
#include "virtualFile.I"
|
||||||
|
|
||||||
|
#endif
|
46
panda/src/putil/virtualFileComposite.I
Normal file
46
panda/src/putil/virtualFileComposite.I
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Filename: virtualFileComposite.I
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileComposite::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE VirtualFileComposite::
|
||||||
|
VirtualFileComposite(VirtualFileSystem *file_system, const Filename &filename) :
|
||||||
|
_file_system(file_system),
|
||||||
|
_filename(filename)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileComposite::add_component
|
||||||
|
// Access: Public
|
||||||
|
// Description: Adds one more component to the composite directory.
|
||||||
|
// The component should be a directory and the file
|
||||||
|
// system and filename should match the composite.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void VirtualFileComposite::
|
||||||
|
add_component(VirtualFile *file) {
|
||||||
|
nassertv(file->is_directory());
|
||||||
|
nassertv(file->get_file_system() == _file_system);
|
||||||
|
nassertv(file->get_filename() == _filename);
|
||||||
|
|
||||||
|
_components.push_back(file);
|
||||||
|
}
|
78
panda/src/putil/virtualFileComposite.cxx
Normal file
78
panda/src/putil/virtualFileComposite.cxx
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
// Filename: virtualFileComposite.cxx
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "virtualFileComposite.h"
|
||||||
|
|
||||||
|
TypeHandle VirtualFileComposite::_type_handle;
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileComposite::get_file_system
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description: Returns the VirtualFileSystem this file is associated
|
||||||
|
// with.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
VirtualFileSystem *VirtualFileComposite::
|
||||||
|
get_file_system() const {
|
||||||
|
return _file_system;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileComposite::get_filename
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description: Returns the full pathname to this file within the
|
||||||
|
// virtual file system.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Filename VirtualFileComposite::
|
||||||
|
get_filename() const {
|
||||||
|
return _filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileComposite::is_directory
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description: Returns true if this file represents a directory (and
|
||||||
|
// scan_directory() may be called), false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileComposite::
|
||||||
|
is_directory() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileComposite::scan_local_directory
|
||||||
|
// Access: Protected, Virtual
|
||||||
|
// Description: Fills file_list up with the list of files that are
|
||||||
|
// within this directory, excluding those whose
|
||||||
|
// basenames are listed in mount_points. Returns true
|
||||||
|
// if successful, false if the file is not a directory
|
||||||
|
// or the directory cannot be read.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileComposite::
|
||||||
|
scan_local_directory(VirtualFileList *file_list,
|
||||||
|
const ov_set<string> &mount_points) const {
|
||||||
|
bool any_ok = false;
|
||||||
|
Components::const_iterator ci;
|
||||||
|
for (ci = _components.begin(); ci != _components.end(); ++ci) {
|
||||||
|
if ((*ci)->scan_local_directory(file_list, mount_points)) {
|
||||||
|
any_ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return any_ok;
|
||||||
|
}
|
79
panda/src/putil/virtualFileComposite.h
Normal file
79
panda/src/putil/virtualFileComposite.h
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// Filename: virtualFileComposite.h
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef VIRTUALFILECOMPOSITE_H
|
||||||
|
#define VIRTUALFILECOMPOSITE_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
#include "virtualFile.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : VirtualFileComposite
|
||||||
|
// Description : A composite directory within the VirtualFileSystem:
|
||||||
|
// this maps to more than one directory on different
|
||||||
|
// mount points. The resulting directory appears to be
|
||||||
|
// the union of all the individual simple directories.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA VirtualFileComposite : public VirtualFile {
|
||||||
|
public:
|
||||||
|
INLINE VirtualFileComposite(VirtualFileSystem *file_system,
|
||||||
|
const Filename &filename);
|
||||||
|
|
||||||
|
INLINE void add_component(VirtualFile *file);
|
||||||
|
|
||||||
|
virtual VirtualFileSystem *get_file_system() const;
|
||||||
|
virtual Filename get_filename() const;
|
||||||
|
|
||||||
|
virtual bool is_directory() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool scan_local_directory(VirtualFileList *file_list,
|
||||||
|
const ov_set<string> &mount_points) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
VirtualFileSystem *_file_system;
|
||||||
|
Filename _filename;
|
||||||
|
typedef pvector< PT(VirtualFile) > Components;
|
||||||
|
Components _components;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual TypeHandle get_type() const {
|
||||||
|
return get_class_type();
|
||||||
|
}
|
||||||
|
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||||
|
|
||||||
|
PUBLISHED:
|
||||||
|
static TypeHandle get_class_type() {
|
||||||
|
return _type_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void init_type() {
|
||||||
|
VirtualFile::init_type();
|
||||||
|
register_type(_type_handle, "VirtualFileComposite",
|
||||||
|
VirtualFile::get_class_type());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static TypeHandle _type_handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "virtualFileComposite.I"
|
||||||
|
|
||||||
|
#endif
|
67
panda/src/putil/virtualFileList.I
Normal file
67
panda/src/putil/virtualFileList.I
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Filename: virtualFileList.I
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileList::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE VirtualFileList::
|
||||||
|
VirtualFileList() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileList::Destructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE VirtualFileList::
|
||||||
|
~VirtualFileList() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileList::add_file
|
||||||
|
// Access: Public
|
||||||
|
// Description: Adds a new file to the list.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void VirtualFileList::
|
||||||
|
add_file(VirtualFile *file) {
|
||||||
|
_files.push_back(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileList::get_num_files
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the number of files in the list.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int VirtualFileList::
|
||||||
|
get_num_files() const {
|
||||||
|
return _files.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileList::get_file
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the nth file in the list.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE VirtualFile *VirtualFileList::
|
||||||
|
get_file(int n) const {
|
||||||
|
nassertr(n >= 0 && n < (int)_files.size(), NULL);
|
||||||
|
return _files[n];
|
||||||
|
}
|
19
panda/src/putil/virtualFileList.cxx
Normal file
19
panda/src/putil/virtualFileList.cxx
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Filename: virtualFileList.cxx
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "virtualFileList.h"
|
53
panda/src/putil/virtualFileList.h
Normal file
53
panda/src/putil/virtualFileList.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Filename: virtualFileList.h
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef VIRTUALFILELIST_H
|
||||||
|
#define VIRTUALFILELIST_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
#include "virtualFile.h"
|
||||||
|
#include "pointerTo.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : VirtualFileList
|
||||||
|
// Description : A list of VirtualFiles, as returned by
|
||||||
|
// VirtualDirectory::scan().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA VirtualFileList : public ReferenceCount {
|
||||||
|
public:
|
||||||
|
INLINE VirtualFileList();
|
||||||
|
|
||||||
|
PUBLISHED:
|
||||||
|
INLINE ~VirtualFileList();
|
||||||
|
|
||||||
|
public:
|
||||||
|
INLINE void add_file(VirtualFile *file);
|
||||||
|
|
||||||
|
PUBLISHED:
|
||||||
|
INLINE int get_num_files() const;
|
||||||
|
INLINE VirtualFile *get_file(int n) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef pvector< PT(VirtualFile) > Files;
|
||||||
|
Files _files;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "virtualFileList.I"
|
||||||
|
|
||||||
|
#endif
|
88
panda/src/putil/virtualFileMount.I
Normal file
88
panda/src/putil/virtualFileMount.I
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
// Filename: virtualFileMount.I
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMount::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE VirtualFileMount::
|
||||||
|
VirtualFileMount(VirtualFileSystem *file_system,
|
||||||
|
const Filename &physical_filename,
|
||||||
|
const Filename &mount_point,
|
||||||
|
int mount_flags) :
|
||||||
|
_file_system(file_system),
|
||||||
|
_physical_filename(physical_filename),
|
||||||
|
_mount_point(mount_point),
|
||||||
|
_mount_flags(mount_flags)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMount::get_file_system
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the file system this mount object is attached
|
||||||
|
// to.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE VirtualFileSystem *VirtualFileMount::
|
||||||
|
get_file_system() const {
|
||||||
|
return _file_system;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMount::get_physical_filename
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the name of the source file on the OS
|
||||||
|
// filesystem of the directory or file that is mounted.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const Filename &VirtualFileMount::
|
||||||
|
get_physical_filename() const {
|
||||||
|
return _physical_filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMount::get_mount_point
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the name of the directory within the virtual
|
||||||
|
// file system that this mount object is attached to.
|
||||||
|
// This directory name will end with a slash.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const Filename &VirtualFileMount::
|
||||||
|
get_mount_point() const {
|
||||||
|
return _mount_point;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMount::get_mount_flags
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the set of flags passed by the user to the
|
||||||
|
// VirtualFileSystem::mount() command.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int VirtualFileMount::
|
||||||
|
get_mount_flags() const {
|
||||||
|
return _mount_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
INLINE ostream &
|
||||||
|
operator << (ostream &out, const VirtualFileMount &mount) {
|
||||||
|
mount.output(out);
|
||||||
|
return out;
|
||||||
|
}
|
51
panda/src/putil/virtualFileMount.cxx
Normal file
51
panda/src/putil/virtualFileMount.cxx
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Filename: virtualFileMount.cxx
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "virtualFileMount.h"
|
||||||
|
|
||||||
|
TypeHandle VirtualFileMount::_type_handle;
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMount::Destructor
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
VirtualFileMount::
|
||||||
|
~VirtualFileMount() {
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMount::output
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void VirtualFileMount::
|
||||||
|
output(ostream &out) const {
|
||||||
|
out << get_physical_filename();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMount::write
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void VirtualFileMount::
|
||||||
|
write(ostream &out) const {
|
||||||
|
out << get_physical_filename() << " on /" << get_mount_point() << "\n";
|
||||||
|
}
|
90
panda/src/putil/virtualFileMount.h
Normal file
90
panda/src/putil/virtualFileMount.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
// Filename: virtualFileMount.h
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef VIRTUALFILEMOUNT_H
|
||||||
|
#define VIRTUALFILEMOUNT_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
#include "filename.h"
|
||||||
|
#include "pointerTo.h"
|
||||||
|
#include "typedObject.h"
|
||||||
|
|
||||||
|
class VirtualFileSystem;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : VirtualFileMount
|
||||||
|
// Description : The abstract base class for a mount definition used
|
||||||
|
// within a VirtualFileSystem. Normally users don't
|
||||||
|
// need to monkey with this class directly.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA VirtualFileMount : public TypedObject {
|
||||||
|
public:
|
||||||
|
INLINE VirtualFileMount(VirtualFileSystem *file_system,
|
||||||
|
const Filename &physical_filename,
|
||||||
|
const Filename &mount_point,
|
||||||
|
int mount_flags);
|
||||||
|
virtual ~VirtualFileMount();
|
||||||
|
|
||||||
|
INLINE VirtualFileSystem *get_file_system() const;
|
||||||
|
INLINE const Filename &get_physical_filename() const;
|
||||||
|
INLINE const Filename &get_mount_point() const;
|
||||||
|
INLINE int get_mount_flags() const;
|
||||||
|
|
||||||
|
virtual bool has_file(const Filename &file) const=0;
|
||||||
|
virtual bool is_directory(const Filename &file) const=0;
|
||||||
|
virtual bool is_regular_file(const Filename &file) const=0;
|
||||||
|
|
||||||
|
virtual istream *open_read_file(const Filename &file) const=0;
|
||||||
|
virtual bool scan_directory(vector_string &contents,
|
||||||
|
const Filename &dir) const=0;
|
||||||
|
|
||||||
|
|
||||||
|
virtual void output(ostream &out) const;
|
||||||
|
virtual void write(ostream &out) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
VirtualFileSystem *_file_system;
|
||||||
|
Filename _physical_filename;
|
||||||
|
Filename _mount_point;
|
||||||
|
int _mount_flags;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual TypeHandle get_type() const {
|
||||||
|
return get_class_type();
|
||||||
|
}
|
||||||
|
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||||
|
static TypeHandle get_class_type() {
|
||||||
|
return _type_handle;
|
||||||
|
}
|
||||||
|
static void init_type() {
|
||||||
|
TypedObject::init_type();
|
||||||
|
register_type(_type_handle, "VirtualFileMount",
|
||||||
|
TypedObject::get_class_type());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static TypeHandle _type_handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
INLINE ostream &operator << (ostream &out, const VirtualFileMount &mount);
|
||||||
|
|
||||||
|
#include "virtualFileMount.I"
|
||||||
|
|
||||||
|
#endif
|
45
panda/src/putil/virtualFileMountMultifile.I
Normal file
45
panda/src/putil/virtualFileMountMultifile.I
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Filename: virtualFileMountMultifile.I
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMountMultifile::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE VirtualFileMountMultifile::
|
||||||
|
VirtualFileMountMultifile(VirtualFileSystem *file_system,
|
||||||
|
Multifile *multifile,
|
||||||
|
const Filename &mount_point,
|
||||||
|
int mount_flags) :
|
||||||
|
VirtualFileMount(file_system, multifile->get_multifile_name(),
|
||||||
|
mount_point, mount_flags),
|
||||||
|
_multifile(multifile)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMountMultifile::get_multifile
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the Multifile pointer that this mount object
|
||||||
|
// is based on.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE Multifile *VirtualFileMountMultifile::
|
||||||
|
get_multifile() const {
|
||||||
|
return _multifile;
|
||||||
|
}
|
99
panda/src/putil/virtualFileMountMultifile.cxx
Normal file
99
panda/src/putil/virtualFileMountMultifile.cxx
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
// Filename: virtualFileMountMultifile.cxx
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "virtualFileMountMultifile.h"
|
||||||
|
#include "virtualFileSystem.h"
|
||||||
|
|
||||||
|
TypeHandle VirtualFileMountMultifile::_type_handle;
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMountMultifile::Destructor
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
VirtualFileMountMultifile::
|
||||||
|
~VirtualFileMountMultifile() {
|
||||||
|
if ((_mount_flags & VirtualFileSystem::MF_owns_pointer) != 0) {
|
||||||
|
// Delete the _multifile pointer if we own it.
|
||||||
|
nassertv(_multifile != (Multifile *)NULL);
|
||||||
|
delete _multifile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMountMultifile::has_file
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns true if the indicated file exists within the
|
||||||
|
// mount system.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileMountMultifile::
|
||||||
|
has_file(const Filename &file) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMountMultifile::is_directory
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns true if the indicated file exists within the
|
||||||
|
// mount system and is a directory.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileMountMultifile::
|
||||||
|
is_directory(const Filename &file) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMountMultifile::is_regular_file
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns true if the indicated file exists within the
|
||||||
|
// mount system and is a regular file.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileMountMultifile::
|
||||||
|
is_regular_file(const Filename &file) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMountMultifile::open_read_file
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Opens the file for reading, if it exists. Returns a
|
||||||
|
// newly allocated istream on success (which you should
|
||||||
|
// eventually delete when you are done reading).
|
||||||
|
// Returns NULL or an invalid istream on failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
istream *VirtualFileMountMultifile::
|
||||||
|
open_read_file(const Filename &file) const {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMountMultifile::scan_directory
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Fills the given vector up with the sorted list of
|
||||||
|
// filenames that are local to this directory, if the
|
||||||
|
// filename is a directory. Returns true if successful,
|
||||||
|
// or false if the file is not a directory or cannot be
|
||||||
|
// read.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileMountMultifile::
|
||||||
|
scan_directory(vector_string &contents, const Filename &dir) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
75
panda/src/putil/virtualFileMountMultifile.h
Normal file
75
panda/src/putil/virtualFileMountMultifile.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
// Filename: virtualFileMountMultifile.h
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef VIRTUALFILEMOUNTMULTIFILE_H
|
||||||
|
#define VIRTUALFILEMOUNTMULTIFILE_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
#include "virtualFileMount.h"
|
||||||
|
#include "multifile.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : VirtualFileMountMultifile
|
||||||
|
// Description : Maps a Multifile's contents into the
|
||||||
|
// VirtualFileSystem.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA VirtualFileMountMultifile : public VirtualFileMount {
|
||||||
|
public:
|
||||||
|
INLINE VirtualFileMountMultifile(VirtualFileSystem *file_system,
|
||||||
|
Multifile *multifile,
|
||||||
|
const Filename &mount_point,
|
||||||
|
int mount_flags);
|
||||||
|
virtual ~VirtualFileMountMultifile();
|
||||||
|
|
||||||
|
INLINE Multifile *get_multifile() const;
|
||||||
|
|
||||||
|
virtual bool has_file(const Filename &file) const;
|
||||||
|
virtual bool is_directory(const Filename &file) const;
|
||||||
|
virtual bool is_regular_file(const Filename &file) const;
|
||||||
|
|
||||||
|
virtual istream *open_read_file(const Filename &file) const;
|
||||||
|
virtual bool scan_directory(vector_string &contents,
|
||||||
|
const Filename &dir) const;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
Multifile *_multifile;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual TypeHandle get_type() const {
|
||||||
|
return get_class_type();
|
||||||
|
}
|
||||||
|
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||||
|
static TypeHandle get_class_type() {
|
||||||
|
return _type_handle;
|
||||||
|
}
|
||||||
|
static void init_type() {
|
||||||
|
VirtualFileMount::init_type();
|
||||||
|
register_type(_type_handle, "VirtualFileMountMultifile",
|
||||||
|
VirtualFileMount::get_class_type());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static TypeHandle _type_handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "virtualFileMountMultifile.I"
|
||||||
|
|
||||||
|
#endif
|
32
panda/src/putil/virtualFileMountSystem.I
Normal file
32
panda/src/putil/virtualFileMountSystem.I
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Filename: virtualFileMountSystem.I
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMountSystem::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE VirtualFileMountSystem::
|
||||||
|
VirtualFileMountSystem(VirtualFileSystem *file_system,
|
||||||
|
const Filename &physical_filename,
|
||||||
|
const Filename &mount_point,
|
||||||
|
int mount_flags) :
|
||||||
|
VirtualFileMount(file_system, physical_filename, mount_point, mount_flags)
|
||||||
|
{
|
||||||
|
}
|
95
panda/src/putil/virtualFileMountSystem.cxx
Normal file
95
panda/src/putil/virtualFileMountSystem.cxx
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// Filename: virtualFileMountSystem.cxx
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "virtualFileMountSystem.h"
|
||||||
|
|
||||||
|
TypeHandle VirtualFileMountSystem::_type_handle;
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMountSystem::has_file
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns true if the indicated file exists within the
|
||||||
|
// mount system.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileMountSystem::
|
||||||
|
has_file(const Filename &file) const {
|
||||||
|
Filename pathname(_physical_filename, file);
|
||||||
|
return pathname.exists();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMountSystem::is_directory
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns true if the indicated file exists within the
|
||||||
|
// mount system and is a directory.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileMountSystem::
|
||||||
|
is_directory(const Filename &file) const {
|
||||||
|
Filename pathname(_physical_filename, file);
|
||||||
|
return pathname.is_directory();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMountSystem::is_regular_file
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns true if the indicated file exists within the
|
||||||
|
// mount system and is a regular file.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileMountSystem::
|
||||||
|
is_regular_file(const Filename &file) const {
|
||||||
|
Filename pathname(_physical_filename, file);
|
||||||
|
return pathname.is_regular_file();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMountSystem::open_read_file
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Opens the file for reading, if it exists. Returns a
|
||||||
|
// newly allocated istream on success (which you should
|
||||||
|
// eventually delete when you are done reading).
|
||||||
|
// Returns NULL or an invalid istream on failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
istream *VirtualFileMountSystem::
|
||||||
|
open_read_file(const Filename &file) const {
|
||||||
|
Filename pathname(_physical_filename, file);
|
||||||
|
ifstream *stream = new ifstream;
|
||||||
|
if (!pathname.open_read(*stream)) {
|
||||||
|
// Couldn't open the file for some reason.
|
||||||
|
delete stream;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileMountSystem::scan_directory
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Fills the given vector up with the sorted list of
|
||||||
|
// filenames that are local to this directory, if the
|
||||||
|
// filename is a directory. Returns true if successful,
|
||||||
|
// or false if the file is not a directory or cannot be
|
||||||
|
// read.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileMountSystem::
|
||||||
|
scan_directory(vector_string &contents, const Filename &dir) const {
|
||||||
|
Filename pathname(_physical_filename, dir);
|
||||||
|
return pathname.scan_directory(contents);
|
||||||
|
}
|
||||||
|
|
68
panda/src/putil/virtualFileMountSystem.h
Normal file
68
panda/src/putil/virtualFileMountSystem.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// Filename: virtualFileMountSystem.h
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef VIRTUALFILEMOUNTSYSTEM_H
|
||||||
|
#define VIRTUALFILEMOUNTSYSTEM_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
#include "virtualFileMount.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : VirtualFileMountSystem
|
||||||
|
// Description : Maps an actual OS directory into the
|
||||||
|
// VirtualFileSystem.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA VirtualFileMountSystem : public VirtualFileMount {
|
||||||
|
public:
|
||||||
|
INLINE VirtualFileMountSystem(VirtualFileSystem *file_system,
|
||||||
|
const Filename &physical_filename,
|
||||||
|
const Filename &mount_point,
|
||||||
|
int mount_flags);
|
||||||
|
|
||||||
|
|
||||||
|
virtual bool has_file(const Filename &file) const;
|
||||||
|
virtual bool is_directory(const Filename &file) const;
|
||||||
|
virtual bool is_regular_file(const Filename &file) const;
|
||||||
|
|
||||||
|
virtual istream *open_read_file(const Filename &file) const;
|
||||||
|
virtual bool scan_directory(vector_string &contents,
|
||||||
|
const Filename &dir) const;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual TypeHandle get_type() const {
|
||||||
|
return get_class_type();
|
||||||
|
}
|
||||||
|
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||||
|
static TypeHandle get_class_type() {
|
||||||
|
return _type_handle;
|
||||||
|
}
|
||||||
|
static void init_type() {
|
||||||
|
VirtualFileMount::init_type();
|
||||||
|
register_type(_type_handle, "VirtualFileMountSystem",
|
||||||
|
VirtualFileMount::get_class_type());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static TypeHandle _type_handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "virtualFileMountSystem.I"
|
||||||
|
|
||||||
|
#endif
|
30
panda/src/putil/virtualFileSimple.I
Normal file
30
panda/src/putil/virtualFileSimple.I
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// Filename: virtualFileSimple.I
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSimple::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE VirtualFileSimple::
|
||||||
|
VirtualFileSimple(VirtualFileMount *mount, const Filename &local_filename) :
|
||||||
|
_mount(mount),
|
||||||
|
_local_filename(local_filename)
|
||||||
|
{
|
||||||
|
}
|
130
panda/src/putil/virtualFileSimple.cxx
Normal file
130
panda/src/putil/virtualFileSimple.cxx
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
// Filename: virtualFileSimple.cxx
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "virtualFileSimple.h"
|
||||||
|
|
||||||
|
TypeHandle VirtualFileSimple::_type_handle;
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSimple::get_file_system
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description: Returns the VirtualFileSystem this file is associated
|
||||||
|
// with.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
VirtualFileSystem *VirtualFileSimple::
|
||||||
|
get_file_system() const {
|
||||||
|
return _mount->get_file_system();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSimple::get_filename
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description: Returns the full pathname to this file within the
|
||||||
|
// virtual file system.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Filename VirtualFileSimple::
|
||||||
|
get_filename() const {
|
||||||
|
string mount_point = _mount->get_mount_point();
|
||||||
|
if (_local_filename.empty()) {
|
||||||
|
if (mount_point.empty()) {
|
||||||
|
return "/";
|
||||||
|
} else {
|
||||||
|
return string("/") + mount_point;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (mount_point.empty()) {
|
||||||
|
return string("/") + _local_filename.get_fullpath();
|
||||||
|
} else {
|
||||||
|
return string("/") + mount_point + string("/") + _local_filename.get_fullpath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSimple::is_directory
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description: Returns true if this file represents a directory (and
|
||||||
|
// scan_directory() may be called), false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileSimple::
|
||||||
|
is_directory() const {
|
||||||
|
return _mount->is_directory(_local_filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSimple::is_regular_file
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description: Returns true if this file represents a regular file
|
||||||
|
// (and read_file() may be called), false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileSimple::
|
||||||
|
is_regular_file() const {
|
||||||
|
return _mount->is_regular_file(_local_filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSimple::open_read_file
|
||||||
|
// Access: Published, Virtual
|
||||||
|
// Description: Opens the file for reading. Returns a newly
|
||||||
|
// allocated istream on success (which you should
|
||||||
|
// eventually delete when you are done reading).
|
||||||
|
// Returns NULL on failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
istream *VirtualFileSimple::
|
||||||
|
open_read_file() const {
|
||||||
|
return _mount->open_read_file(_local_filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSimple::scan_local_directory
|
||||||
|
// Access: Protected, Virtual
|
||||||
|
// Description: Fills file_list up with the list of files that are
|
||||||
|
// within this directory, excluding those whose
|
||||||
|
// basenames are listed in mount_points. Returns true
|
||||||
|
// if successful, false if the file is not a directory
|
||||||
|
// or the directory cannot be read.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileSimple::
|
||||||
|
scan_local_directory(VirtualFileList *file_list,
|
||||||
|
const ov_set<string> &mount_points) const {
|
||||||
|
vector_string names;
|
||||||
|
if (!_mount->scan_directory(names, _local_filename)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now the scan above gave us a list of basenames. Turn these back
|
||||||
|
// into VirtualFile pointers.
|
||||||
|
|
||||||
|
// Each of the files returned by the mount will be just a simple
|
||||||
|
// file within the same mount tree, unless it is shadowed by a
|
||||||
|
// mount point listed in mount_points.
|
||||||
|
|
||||||
|
vector_string::const_iterator ni;
|
||||||
|
for (ni = names.begin(); ni != names.end(); ++ni) {
|
||||||
|
const string &basename = (*ni);
|
||||||
|
if (mount_points.find(basename) == mount_points.end()) {
|
||||||
|
Filename filename(_local_filename, basename);
|
||||||
|
VirtualFileSimple *file = new VirtualFileSimple(_mount, filename);
|
||||||
|
file_list->add_file(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
78
panda/src/putil/virtualFileSimple.h
Normal file
78
panda/src/putil/virtualFileSimple.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
// Filename: virtualFileSimple.h
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef VIRTUALFILESIMPLE_H
|
||||||
|
#define VIRTUALFILESIMPLE_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
#include "virtualFile.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : VirtualFileSimple
|
||||||
|
// Description : A simple file or directory within the
|
||||||
|
// VirtualFileSystem: this maps to exactly one file on
|
||||||
|
// one mount point. Most directories, and all regular
|
||||||
|
// files, are of this kind.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA VirtualFileSimple : public VirtualFile {
|
||||||
|
public:
|
||||||
|
INLINE VirtualFileSimple(VirtualFileMount *mount,
|
||||||
|
const Filename &local_filename);
|
||||||
|
|
||||||
|
virtual VirtualFileSystem *get_file_system() const;
|
||||||
|
virtual Filename get_filename() const;
|
||||||
|
|
||||||
|
virtual bool is_directory() const;
|
||||||
|
virtual bool is_regular_file() const;
|
||||||
|
|
||||||
|
virtual istream *open_read_file() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool scan_local_directory(VirtualFileList *file_list,
|
||||||
|
const ov_set<string> &mount_points) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
VirtualFileMount *_mount;
|
||||||
|
Filename _local_filename;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual TypeHandle get_type() const {
|
||||||
|
return get_class_type();
|
||||||
|
}
|
||||||
|
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||||
|
|
||||||
|
PUBLISHED:
|
||||||
|
static TypeHandle get_class_type() {
|
||||||
|
return _type_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void init_type() {
|
||||||
|
VirtualFile::init_type();
|
||||||
|
register_type(_type_handle, "VirtualFileSimple",
|
||||||
|
VirtualFile::get_class_type());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static TypeHandle _type_handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "virtualFileSimple.I"
|
||||||
|
|
||||||
|
#endif
|
17
panda/src/putil/virtualFileSystem.I
Normal file
17
panda/src/putil/virtualFileSystem.I
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Filename: virtualFileSystem.I
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
500
panda/src/putil/virtualFileSystem.cxx
Normal file
500
panda/src/putil/virtualFileSystem.cxx
Normal file
@ -0,0 +1,500 @@
|
|||||||
|
// Filename: virtualFileSystem.cxx
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "virtualFileSystem.h"
|
||||||
|
#include "virtualFileMount.h"
|
||||||
|
#include "virtualFileMountMultifile.h"
|
||||||
|
#include "virtualFileMountSystem.h"
|
||||||
|
#include "dSearchPath.h"
|
||||||
|
#include "dcast.h"
|
||||||
|
|
||||||
|
VirtualFileSystem *VirtualFileSystem::_global_ptr = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::Constructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
VirtualFileSystem::
|
||||||
|
VirtualFileSystem() {
|
||||||
|
_cwd = "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::Destructor
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
VirtualFileSystem::
|
||||||
|
~VirtualFileSystem() {
|
||||||
|
unmount_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::mount
|
||||||
|
// Access: Published
|
||||||
|
// Description: Mounts the indicated Multifile at the given mount
|
||||||
|
// point. If flags contains MF_owns_pointer, the
|
||||||
|
// Multifile will be deleted when it is eventually
|
||||||
|
// unmounted.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileSystem::
|
||||||
|
mount(Multifile *multifile, const string &mount_point, int flags) {
|
||||||
|
VirtualFileMountMultifile *mount =
|
||||||
|
new VirtualFileMountMultifile(this, multifile,
|
||||||
|
normalize_mount_point(mount_point),
|
||||||
|
flags);
|
||||||
|
_mounts.push_back(mount);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::mount
|
||||||
|
// Access: Published
|
||||||
|
// Description: Mounts the indicated system file or directory at the
|
||||||
|
// given mount point. If the named file is a directory,
|
||||||
|
// mounts the directory. If the named file is a
|
||||||
|
// Multifile, mounts it as a Multifile. Returns true on
|
||||||
|
// success, false on failure.
|
||||||
|
//
|
||||||
|
// A given system directory may be mounted to multiple
|
||||||
|
// different mount point, and the same mount point may
|
||||||
|
// share multiple system directories. In the case of
|
||||||
|
// ambiguities, the most-recently mounted system wins.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileSystem::
|
||||||
|
mount(const Filename &physical_filename, const string &mount_point,
|
||||||
|
int flags) {
|
||||||
|
if (!physical_filename.exists()) {
|
||||||
|
util_cat.warning()
|
||||||
|
<< "Attempt to mount " << physical_filename << ", not found.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (physical_filename.is_directory()) {
|
||||||
|
flags &= ~MF_owns_pointer;
|
||||||
|
VirtualFileMountSystem *mount =
|
||||||
|
new VirtualFileMountSystem(this, physical_filename,
|
||||||
|
normalize_mount_point(mount_point),
|
||||||
|
flags);
|
||||||
|
_mounts.push_back(mount);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// It's not a directory; it must be a Multifile.
|
||||||
|
Multifile *multifile = new Multifile;
|
||||||
|
|
||||||
|
// For now these are always opened read only. Maybe later we'll
|
||||||
|
// support read-write on Multifiles.
|
||||||
|
flags |= MF_read_only;
|
||||||
|
if (!multifile->open_read(physical_filename)) {
|
||||||
|
delete multifile;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We want to delete this pointer when we're done.
|
||||||
|
flags |= MF_owns_pointer;
|
||||||
|
return mount(multifile, mount_point, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::unmount
|
||||||
|
// Access: Published
|
||||||
|
// Description: Unmounts all appearances of the indicated Multifile
|
||||||
|
// from the file system. Returns the number of
|
||||||
|
// appearances unmounted.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int VirtualFileSystem::
|
||||||
|
unmount(Multifile *multifile) {
|
||||||
|
Mounts::iterator ri, wi;
|
||||||
|
wi = ri = _mounts.begin();
|
||||||
|
while (ri != _mounts.end()) {
|
||||||
|
VirtualFileMount *mount = (*ri);
|
||||||
|
(*wi) = mount;
|
||||||
|
|
||||||
|
if (mount->is_exact_type(VirtualFileMountMultifile::get_class_type())) {
|
||||||
|
VirtualFileMountMultifile *mmount =
|
||||||
|
DCAST(VirtualFileMountMultifile, mount);
|
||||||
|
if (mmount->get_multifile() == multifile) {
|
||||||
|
// Remove this one. Don't increment wi.
|
||||||
|
delete mount;
|
||||||
|
} else {
|
||||||
|
// Don't remove this one.
|
||||||
|
++wi;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Don't remove this one.
|
||||||
|
++wi;
|
||||||
|
}
|
||||||
|
++ri;
|
||||||
|
}
|
||||||
|
|
||||||
|
int num_removed = _mounts.end() - wi;
|
||||||
|
_mounts.erase(wi, _mounts.end());
|
||||||
|
return num_removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::unmount
|
||||||
|
// Access: Published
|
||||||
|
// Description: Unmounts all appearances of the indicated physical
|
||||||
|
// filename (either a directory name or a Multifile
|
||||||
|
// name) from the file system. Returns the number of
|
||||||
|
// appearances unmounted.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int VirtualFileSystem::
|
||||||
|
unmount(const Filename &physical_filename) {
|
||||||
|
Mounts::iterator ri, wi;
|
||||||
|
wi = ri = _mounts.begin();
|
||||||
|
while (ri != _mounts.end()) {
|
||||||
|
VirtualFileMount *mount = (*ri);
|
||||||
|
(*wi) = mount;
|
||||||
|
|
||||||
|
if (mount->get_physical_filename() == physical_filename) {
|
||||||
|
// Remove this one. Don't increment wi.
|
||||||
|
delete mount;
|
||||||
|
} else {
|
||||||
|
// Don't remove this one.
|
||||||
|
++wi;
|
||||||
|
}
|
||||||
|
++ri;
|
||||||
|
}
|
||||||
|
|
||||||
|
int num_removed = _mounts.end() - wi;
|
||||||
|
_mounts.erase(wi, _mounts.end());
|
||||||
|
return num_removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::unmount_point
|
||||||
|
// Access: Published
|
||||||
|
// Description: Unmounts all systems attached to the given mount
|
||||||
|
// point from the file system. Returns the number of
|
||||||
|
// appearances unmounted.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int VirtualFileSystem::
|
||||||
|
unmount_point(const string &mount_point) {
|
||||||
|
Filename nmp = normalize_mount_point(mount_point);
|
||||||
|
Mounts::iterator ri, wi;
|
||||||
|
wi = ri = _mounts.begin();
|
||||||
|
while (ri != _mounts.end()) {
|
||||||
|
VirtualFileMount *mount = (*ri);
|
||||||
|
(*wi) = mount;
|
||||||
|
|
||||||
|
if (mount->get_mount_point() == nmp) {
|
||||||
|
// Remove this one. Don't increment wi.
|
||||||
|
delete mount;
|
||||||
|
} else {
|
||||||
|
// Don't remove this one.
|
||||||
|
++wi;
|
||||||
|
}
|
||||||
|
++ri;
|
||||||
|
}
|
||||||
|
|
||||||
|
int num_removed = _mounts.end() - wi;
|
||||||
|
_mounts.erase(wi, _mounts.end());
|
||||||
|
return num_removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::unmount_all
|
||||||
|
// Access: Published
|
||||||
|
// Description: Unmounts all files from the file system. Returns the
|
||||||
|
// number of systems unmounted.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int VirtualFileSystem::
|
||||||
|
unmount_all() {
|
||||||
|
Mounts::iterator mi;
|
||||||
|
for (mi = _mounts.begin(); mi != _mounts.end(); ++mi) {
|
||||||
|
VirtualFileMount *mount = (*mi);
|
||||||
|
delete mount;
|
||||||
|
}
|
||||||
|
|
||||||
|
int num_removed = _mounts.size();
|
||||||
|
_mounts.clear();
|
||||||
|
return num_removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::chdir
|
||||||
|
// Access: Published
|
||||||
|
// Description: Changes the current directory. This is used to
|
||||||
|
// resolve relative pathnames in get_file() and/or
|
||||||
|
// find_file(). Returns true if successful, false
|
||||||
|
// otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileSystem::
|
||||||
|
chdir(const Filename &new_directory) {
|
||||||
|
if (new_directory == "/") {
|
||||||
|
// We can always return to the root.
|
||||||
|
_cwd = new_directory;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PT(VirtualFile) file = get_file(new_directory);
|
||||||
|
if (file != (VirtualFile *)NULL && file->is_directory()) {
|
||||||
|
_cwd = file->get_filename();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::get_cwd
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the current directory name. See chdir().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
const Filename &VirtualFileSystem::
|
||||||
|
get_cwd() const {
|
||||||
|
return _cwd;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::get_file
|
||||||
|
// Access: Published
|
||||||
|
// Description: Looks up the file by the indicated name in the file
|
||||||
|
// system. Returns a VirtualFile pointer representing
|
||||||
|
// the file if it is found, or NULL if it is not.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PT(VirtualFile) VirtualFileSystem::
|
||||||
|
get_file(const Filename &file) const {
|
||||||
|
nassertr(!file.empty(), NULL);
|
||||||
|
Filename pathname(file);
|
||||||
|
if (pathname.is_local()) {
|
||||||
|
pathname = Filename(_cwd, file);
|
||||||
|
}
|
||||||
|
pathname.standardize();
|
||||||
|
string strpath = pathname.get_fullpath().substr(1);
|
||||||
|
|
||||||
|
// Now scan all the mount points, from the back (since later mounts
|
||||||
|
// override more recent ones), until a match is found.
|
||||||
|
PT(VirtualFile) found_file = NULL;
|
||||||
|
VirtualFileComposite *composite_file = NULL;
|
||||||
|
|
||||||
|
Mounts::const_reverse_iterator rmi;
|
||||||
|
for (rmi = _mounts.rbegin(); rmi != _mounts.rend(); ++rmi) {
|
||||||
|
VirtualFileMount *mount = (*rmi);
|
||||||
|
string mount_point = mount->get_mount_point();
|
||||||
|
if (strpath == mount_point) {
|
||||||
|
// Here's an exact match on the mount point. This filename is
|
||||||
|
// the root directory of this mount object.
|
||||||
|
if (found_match(found_file, composite_file, mount, "")) {
|
||||||
|
return found_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (mount_point.empty()) {
|
||||||
|
// This is the root mount point; all files are in here.
|
||||||
|
if (mount->has_file(strpath)) {
|
||||||
|
// Bingo!
|
||||||
|
if (found_match(found_file, composite_file, mount, strpath)) {
|
||||||
|
return found_file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (strpath.length() > mount_point.length() &&
|
||||||
|
strpath.substr(0, mount_point.length()) == mount_point &&
|
||||||
|
strpath[mount_point.length()] == '/') {
|
||||||
|
// This pathname falls within this mount system.
|
||||||
|
Filename local_filename = strpath.substr(mount_point.length() + 1);
|
||||||
|
if (mount->has_file(local_filename)) {
|
||||||
|
// Bingo!
|
||||||
|
if (found_match(found_file, composite_file, mount, local_filename)) {
|
||||||
|
return found_file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::find_file
|
||||||
|
// Access: Published
|
||||||
|
// Description: Uses the indicated search path to find the file
|
||||||
|
// within the file system. Returns the first occurrence
|
||||||
|
// of the file found, or NULL if the file cannot be
|
||||||
|
// found.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PT(VirtualFile) VirtualFileSystem::
|
||||||
|
find_file(const Filename &file, const DSearchPath &searchpath) const {
|
||||||
|
if (file.is_local()) {
|
||||||
|
return get_file(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
int num_directories = searchpath.get_num_directories();
|
||||||
|
for (int i = 0; i < num_directories; i++) {
|
||||||
|
Filename match(searchpath.get_directory(i), file);
|
||||||
|
PT(VirtualFile) found_file = get_file(match);
|
||||||
|
if (found_file != (VirtualFile *)NULL) {
|
||||||
|
return found_file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::write
|
||||||
|
// Access: Published
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void VirtualFileSystem::
|
||||||
|
write(ostream &out) const {
|
||||||
|
Mounts::const_iterator mi;
|
||||||
|
for (mi = _mounts.begin(); mi != _mounts.end(); ++mi) {
|
||||||
|
VirtualFileMount *mount = (*mi);
|
||||||
|
mount->write(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::get_global_ptr
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Returns the default global VirtualFileSystem. You
|
||||||
|
// may create your own personal VirtualFileSystem
|
||||||
|
// objects and use them for whatever you like, but Panda
|
||||||
|
// will attempt to load models and stuff from this
|
||||||
|
// default object.
|
||||||
|
//
|
||||||
|
// Initially, the global VirtualFileSystem is set up to
|
||||||
|
// mount the OS filesystem to root; i.e. it is
|
||||||
|
// equivalent to the OS filesystem. This may be
|
||||||
|
// subsequently adjusted by the user.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
VirtualFileSystem *VirtualFileSystem::
|
||||||
|
get_global_ptr() {
|
||||||
|
if (_global_ptr == (VirtualFileSystem *)NULL) {
|
||||||
|
_global_ptr = new VirtualFileSystem;
|
||||||
|
_global_ptr->mount("/", "/", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _global_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::scan_mount_points
|
||||||
|
// Access: Public
|
||||||
|
// Description: Adds to names a list of all the mount points in use
|
||||||
|
// that are one directory below path, if any. That is,
|
||||||
|
// these are the external files or directories mounted
|
||||||
|
// directly to the indicated path.
|
||||||
|
//
|
||||||
|
// The names vector is filled with a set of basenames,
|
||||||
|
// the basename part of the mount point.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void VirtualFileSystem::
|
||||||
|
scan_mount_points(vector_string &names, const Filename &path) const {
|
||||||
|
nassertv(!path.empty() && !path.is_local());
|
||||||
|
string prefix = path.get_fullpath().substr(1);
|
||||||
|
Mounts::const_iterator mi;
|
||||||
|
for (mi = _mounts.begin(); mi != _mounts.end(); ++mi) {
|
||||||
|
VirtualFileMount *mount = (*mi);
|
||||||
|
|
||||||
|
string mount_point = mount->get_mount_point();
|
||||||
|
if (prefix.empty()) {
|
||||||
|
// The indicated path is the root. Is the mount point on the
|
||||||
|
// root?
|
||||||
|
if (mount_point.find('/') == string::npos) {
|
||||||
|
// No embedded slashes, so the mount point is only one
|
||||||
|
// directory below the root.
|
||||||
|
names.push_back(mount_point);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mount_point.substr(0, prefix.length()) == prefix &&
|
||||||
|
mount_point.length() > prefix.length() &&
|
||||||
|
mount_point[prefix.length()] == '/') {
|
||||||
|
// This mount point is below the indicated path. Is it only one
|
||||||
|
// directory below?
|
||||||
|
string basename = mount_point.substr(prefix.length());
|
||||||
|
if (basename.find('/') == string::npos) {
|
||||||
|
// No embedded slashes, so it's only one directory below.
|
||||||
|
names.push_back(basename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::normalize_mount_point
|
||||||
|
// Access: Private
|
||||||
|
// Description: Converts the mount point string supplied by the user
|
||||||
|
// to standard form (relative to the current directory,
|
||||||
|
// with no double slashes, and not terminating with a
|
||||||
|
// slash). The initial slash is removed.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Filename VirtualFileSystem::
|
||||||
|
normalize_mount_point(const string &mount_point) const {
|
||||||
|
Filename nmp = mount_point;
|
||||||
|
if (nmp.is_local()) {
|
||||||
|
nmp = Filename(_cwd, mount_point);
|
||||||
|
}
|
||||||
|
nmp.standardize();
|
||||||
|
nassertr(!nmp.empty() && nmp[0] == '/', nmp);
|
||||||
|
return nmp.get_fullpath().substr(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: VirtualFileSystem::found_match
|
||||||
|
// Access: Private
|
||||||
|
// Description: Evaluates one match found during a get_file()
|
||||||
|
// operation. There may be multiple matches for a
|
||||||
|
// particular filename due to the ambiguities introduced
|
||||||
|
// by allowing multiple mount points, so we may have to
|
||||||
|
// keep searching even after the first match is found.
|
||||||
|
//
|
||||||
|
// Returns true if the search should terminate now, or
|
||||||
|
// false if it should keep iterating.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool VirtualFileSystem::
|
||||||
|
found_match(PT(VirtualFile) &found_file, VirtualFileComposite *&composite_file,
|
||||||
|
VirtualFileMount *mount, const string &local_filename) const {
|
||||||
|
if (found_file == (VirtualFile *)NULL) {
|
||||||
|
// This was our first match. Save it.
|
||||||
|
found_file = new VirtualFileSimple(mount, local_filename);
|
||||||
|
if (!mount->is_directory(local_filename)) {
|
||||||
|
// If it's not a directory, we're done.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// This was our second match. The previous match(es) must
|
||||||
|
// have been directories.
|
||||||
|
if (!mount->is_directory(local_filename)) {
|
||||||
|
// However, this one isn't a directory. We're done.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// At least two directories matched to the same path. We
|
||||||
|
// need a composite directory.
|
||||||
|
if (composite_file == (VirtualFileComposite *)NULL) {
|
||||||
|
composite_file =
|
||||||
|
new VirtualFileComposite((VirtualFileSystem *)this, found_file->get_filename());
|
||||||
|
composite_file->add_component(found_file);
|
||||||
|
found_file = composite_file;
|
||||||
|
}
|
||||||
|
composite_file->add_component(new VirtualFileSimple(mount, local_filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep going, looking for more directories.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
86
panda/src/putil/virtualFileSystem.h
Normal file
86
panda/src/putil/virtualFileSystem.h
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// Filename: virtualFileSystem.h
|
||||||
|
// Created by: drose (03Aug02)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef VIRTUALFILESYSTEM_H
|
||||||
|
#define VIRTUALFILESYSTEM_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
#include "filename.h"
|
||||||
|
#include "pmap.h"
|
||||||
|
|
||||||
|
class Multifile;
|
||||||
|
class VirtualFileMount;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : VirtualFileSystem
|
||||||
|
// Description : A hierarchy of directories and files that appears to
|
||||||
|
// be one continuous file system, even though the files
|
||||||
|
// may originate from several different sources that may
|
||||||
|
// not be related to the actual OS's file system.
|
||||||
|
//
|
||||||
|
// For instance, a VirtualFileSystem can transparently
|
||||||
|
// mount one or more Multifiles as their own
|
||||||
|
// subdirectory hierarchies.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA VirtualFileSystem {
|
||||||
|
PUBLISHED:
|
||||||
|
VirtualFileSystem();
|
||||||
|
~VirtualFileSystem();
|
||||||
|
|
||||||
|
enum MountFlags {
|
||||||
|
MF_owns_pointer = 0x0001,
|
||||||
|
MF_read_only = 0x0002,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool mount(Multifile *multifile, const string &mount_point, int flags);
|
||||||
|
bool mount(const Filename &physical_filename, const string &mount_point, int flags);
|
||||||
|
int unmount(Multifile *multifile);
|
||||||
|
int unmount(const Filename &physical_filename);
|
||||||
|
int unmount_point(const string &mount_point);
|
||||||
|
int unmount_all();
|
||||||
|
|
||||||
|
bool chdir(const Filename &new_directory);
|
||||||
|
const Filename &get_cwd() const;
|
||||||
|
|
||||||
|
PT(VirtualFile) get_file(const Filename &file) const;
|
||||||
|
PT(VirtualFile) find_file(const Filename &file,
|
||||||
|
const DSearchPath &searchpath) const;
|
||||||
|
|
||||||
|
void write(ostream &out) const;
|
||||||
|
|
||||||
|
static VirtualFileSystem *get_global_ptr();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void scan_mount_points(vector_string &names, const Filename &path) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Filename normalize_mount_point(const string &mount_point) const;
|
||||||
|
bool found_match(PT(VirtualFile) &found_file, VirtualFileComposite *&composite_file,
|
||||||
|
VirtualFileMount *mount, const string &local_filename) const;
|
||||||
|
|
||||||
|
typedef pvector<VirtualFileMount *> Mounts;
|
||||||
|
Mounts _mounts;
|
||||||
|
Filename _cwd;
|
||||||
|
|
||||||
|
static VirtualFileSystem *_global_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "virtualFileSystem.I"
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user