loader uses vfs

This commit is contained in:
David Rose 2002-08-04 16:58:35 +00:00
parent c1db2dc152
commit fa59c3e37f
27 changed files with 541 additions and 136 deletions

View File

@ -94,12 +94,15 @@ add_directory(Multifile &multifile, const Filename &directory_name) {
okflag = false;
} else {
if (verbose) {
cout << subfile_name << "\n";
}
if (!multifile.add_subfile(subfile_name, subfile_name)) {
string new_subfile_name =
multifile.add_subfile(subfile_name, subfile_name);
if (new_subfile_name.empty()) {
cerr << "Unable to add " << subfile_name << ".\n";
okflag = false;
} else {
if (verbose) {
cout << new_subfile_name << "\n";
}
}
}
}
@ -140,12 +143,15 @@ add_files(int argc, char *argv[]) {
okflag = false;
} else {
if (verbose) {
cout << subfile_name << "\n";
}
if (!multifile.add_subfile(subfile_name, subfile_name)) {
string new_subfile_name =
multifile.add_subfile(subfile_name, subfile_name);
if (new_subfile_name.empty()) {
cerr << "Unable to add " << subfile_name << ".\n";
okflag = false;
} else {
if (verbose) {
cout << new_subfile_name << "\n";
}
}
}
}

View File

@ -24,9 +24,10 @@
#include "eggPoolUniquifier.h"
#include "config_egg.h"
#include <config_util.h>
#include <string_utils.h>
#include <dSearchPath.h>
#include "config_util.h"
#include "string_utils.h"
#include "dSearchPath.h"
#include "virtualFileSystem.h"
extern int eggyyparse(void);
#include "parserDefs.h"
@ -45,15 +46,30 @@ TypeHandle EggData::_type_handle;
////////////////////////////////////////////////////////////////////
bool EggData::
resolve_egg_filename(Filename &egg_filename, const DSearchPath &searchpath) {
if (egg_filename.is_fully_qualified() && egg_filename.exists()) {
return true;
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
if (egg_filename.is_fully_qualified() && vfs->exists(egg_filename)) {
return true;
}
vfs->resolve_filename(egg_filename, searchpath, "egg") ||
vfs->resolve_filename(egg_filename, get_egg_path(), "egg") ||
vfs->resolve_filename(egg_filename, get_model_path(), "egg");
return vfs->exists(egg_filename);
} else {
if (egg_filename.is_fully_qualified() && egg_filename.exists()) {
return true;
}
egg_filename.resolve_filename(searchpath, "egg") ||
egg_filename.resolve_filename(get_egg_path(), "egg") ||
egg_filename.resolve_filename(get_model_path(), "egg");
return egg_filename.exists();
}
egg_filename.resolve_filename(searchpath, "egg") ||
egg_filename.resolve_filename(get_egg_path(), "egg") ||
egg_filename.resolve_filename(get_model_path(), "egg");
return egg_filename.exists();
}
////////////////////////////////////////////////////////////////////
@ -76,19 +92,46 @@ read(Filename filename) {
return false;
}
filename.set_text();
set_egg_filename(filename);
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
filename.set_text();
set_egg_filename(filename);
istream *file = vfs->open_read_file(filename);
if (file == (istream *)NULL) {
egg_cat.error() << "Unable to open " << filename << "\n";
return false;
}
egg_cat.info()
<< "Reading " << filename << "\n";
ifstream file;
if (!filename.open_read(file)) {
egg_cat.error() << "Unable to open " << filename << "\n";
return false;
bool read_ok = read(*file);
delete file;
return read_ok;
} else {
if (!resolve_egg_filename(filename)) {
egg_cat.error()
<< "Could not find " << filename << "\n";
return false;
}
filename.set_text();
set_egg_filename(filename);
ifstream file;
if (!filename.open_read(file)) {
egg_cat.error() << "Unable to open " << filename << "\n";
return false;
}
egg_cat.info()
<< "Reading " << filename << "\n";
return read(file);
}
egg_cat.info()
<< "Reading " << filename << "\n";
return read(file);
}

View File

@ -20,6 +20,8 @@
#include "eggLoader.h"
#include "config_egg2pg.h"
#include "sceneGraphReducer.h"
#include "virtualFileSystem.h"
#include "config_util.h"
static PT(PandaNode)
load_from_loader(EggLoader &loader) {
@ -54,29 +56,56 @@ load_from_loader(EggLoader &loader) {
PT(PandaNode)
load_egg_file(const string &filename, CoordinateSystem cs) {
Filename egg_filename = Filename::text_filename(filename);
if (!egg_filename.exists()) {
egg2pg_cat.error()
<< "Could not find " << egg_filename << "\n";
return NULL;
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
if (!vfs->exists(egg_filename)) {
egg2pg_cat.error()
<< "Could not find " << egg_filename << "\n";
return NULL;
}
} else {
if (!egg_filename.exists()) {
egg2pg_cat.error()
<< "Could not find " << egg_filename << "\n";
return NULL;
}
}
egg2pg_cat.info()
<< "Reading " << egg_filename << "\n";
ifstream file;
if (!egg_filename.open_read(file)) {
egg2pg_cat.error()
<< "Could not open " << egg_filename << " for reading.\n";
return NULL;
}
EggLoader loader;
loader._data.set_egg_filename(egg_filename);
if (cs != CS_default) {
loader._data.set_coordinate_system(cs);
}
bool okflag;
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
istream *istr = vfs->open_read_file(egg_filename);
if (istr == (istream *)NULL) {
egg2pg_cat.error()
<< "Could not open " << egg_filename << " for reading.\n";
return NULL;
}
okflag = loader._data.read(*istr);
delete istr;
if (!loader._data.read(file)) {
} else {
ifstream file;
if (!egg_filename.open_read(file)) {
egg2pg_cat.error()
<< "Could not open " << egg_filename << " for reading.\n";
return NULL;
}
okflag = loader._data.read(file);
}
if (!okflag) {
egg2pg_cat.error()
<< "Error reading " << egg_filename << "\n";
return NULL;

View File

@ -13,9 +13,8 @@
checksumHashGenerator.I checksumHashGenerator.h circBuffer.I \
circBuffer.h clockObject.I clockObject.h config_express.h \
datagram.I datagram.h datagramGenerator.I \
datagramGenerator.h datagramInputFile.I datagramInputFile.h \
datagramIterator.I datagramIterator.h datagramOutputFile.I \
datagramOutputFile.h datagramSink.I datagramSink.h \
datagramGenerator.h \
datagramIterator.I datagramIterator.h datagramSink.I datagramSink.h \
dcast.T dcast.h \
error_utils.h \
get_config_path.h hashGeneratorBase.I hashGeneratorBase.h \
@ -51,8 +50,8 @@
#define INCLUDED_SOURCES \
buffer.cxx checksumHashGenerator.cxx clockObject.cxx \
config_express.cxx datagram.cxx datagramGenerator.cxx \
datagramInputFile.cxx datagramIterator.cxx \
datagramOutputFile.cxx datagramSink.cxx dcast.cxx error_utils.cxx \
datagramIterator.cxx \
datagramSink.cxx dcast.cxx error_utils.cxx \
get_config_path.cxx \
hashGeneratorBase.cxx hashVal.cxx indent.cxx \
memoryInfo.cxx memoryUsage.cxx memoryUsagePointerCounts.cxx \
@ -71,10 +70,9 @@
bigEndian.h buffer.I buffer.h checksumHashGenerator.I \
checksumHashGenerator.h circBuffer.I circBuffer.h clockObject.I \
clockObject.h config_express.h datagram.I datagram.h \
datagramGenerator.I datagramGenerator.h datagramInputFile.I \
datagramInputFile.h datagramIterator.I datagramIterator.h \
datagramOutputFile.I datagramOutputFile.h datagramSink.I \
datagramSink.h dcast.T dcast.h \
datagramGenerator.I datagramGenerator.h \
datagramIterator.I datagramIterator.h \
datagramSink.I datagramSink.h dcast.T dcast.h \
error_utils.h get_config_path.h hashGeneratorBase.I \
hashGeneratorBase.h hashVal.I hashVal.h \
indent.I indent.h \

View File

@ -5,9 +5,7 @@
#include "config_express.cxx"
#include "datagram.cxx"
#include "datagramGenerator.cxx"
#include "datagramInputFile.cxx"
#include "datagramIterator.cxx"
#include "datagramOutputFile.cxx"
#include "datagramSink.cxx"
#include "dcast.cxx"
#include "get_config_path.cxx"

View File

@ -114,9 +114,7 @@ normalize_streampos(streampos fpos) const {
// Description:
////////////////////////////////////////////////////////////////////
INLINE Multifile::Subfile::
Subfile(const string &name) :
_name(name)
{
Subfile() {
_index_start = 0;
_data_start = 0;
_data_length = 0;

View File

@ -288,21 +288,21 @@ set_scale_factor(size_t scale_factor) {
// The file named by filename will be read and added to
// the Multifile at the next call to flush().
//
// Returns true on success, false on failure.
// Returns the subfile name on success (it might have
// been modified slightly), or empty string on failure.
////////////////////////////////////////////////////////////////////
bool Multifile::
string Multifile::
add_subfile(const string &subfile_name, const Filename &filename) {
nassertr(is_write_valid(), false);
nassertr(is_write_valid(), string());
if (!filename.exists()) {
return false;
return string();
}
Subfile *subfile = new Subfile(subfile_name);
Subfile *subfile = new Subfile;
subfile->_source_filename = filename;
subfile->_source_filename.set_binary();
return add_new_subfile(subfile);
return add_new_subfile(subfile_name, subfile);
}
////////////////////////////////////////////////////////////////////
@ -537,7 +537,8 @@ get_num_subfiles() const {
////////////////////////////////////////////////////////////////////
int Multifile::
find_subfile(const string &subfile_name) const {
Subfile find_subfile(subfile_name);
Subfile find_subfile;
find_subfile._name = subfile_name;
Subfiles::const_iterator fi;
fi = _subfiles.find(&find_subfile);
if (fi == _subfiles.end()) {
@ -561,7 +562,8 @@ has_directory(const string &subfile_name) const {
if (!prefix.empty()) {
prefix += '/';
}
Subfile find_subfile(prefix);
Subfile find_subfile;
find_subfile._name = prefix;
Subfiles::const_iterator fi;
fi = _subfiles.upper_bound(&find_subfile);
if (fi == _subfiles.end()) {
@ -597,7 +599,8 @@ scan_directory(vector_string &contents, const string &subfile_name) const {
if (!prefix.empty()) {
prefix += '/';
}
Subfile find_subfile(prefix);
Subfile find_subfile;
find_subfile._name = prefix;
Subfiles::const_iterator fi;
fi = _subfiles.upper_bound(&find_subfile);
@ -818,16 +821,18 @@ open_read_write(iostream *multifile_stream) {
// Description: Adds a file on disk as a subfile to the Multifile.
// The indicated istream will be read and its contents
// added to the Multifile at the next call to flush().
//
// Returns the subfile name on success (it might have
// been modified slightly), or empty string on failure.
////////////////////////////////////////////////////////////////////
bool Multifile::
string Multifile::
add_subfile(const string &subfile_name, istream *subfile_data) {
nassertr(is_write_valid(), false);
Subfile *subfile = new Subfile(subfile_name);
nassertr(is_write_valid(), string());
Subfile *subfile = new Subfile;
subfile->_source = subfile_data;
return add_new_subfile(subfile);
return add_new_subfile(subfile_name, subfile);
}
////////////////////////////////////////////////////////////////////
@ -930,14 +935,28 @@ pad_to_streampos(streampos fpos) {
// Description: Adds a newly-allocated Subfile pointer to the
// Multifile.
////////////////////////////////////////////////////////////////////
bool Multifile::
add_new_subfile(Subfile *subfile) {
string Multifile::
add_new_subfile(const string &subfile_name, Subfile *subfile) {
if (_next_index != (streampos)0) {
// If we're adding a Subfile to an already-existing Multifile, we
// will eventually need to repack the file.
_needs_repack = true;
}
// Normalize the Subfile name: eliminate ./, leading slash, etc.
Filename name = subfile_name;
name.standardize();
if (name.empty() || name == "/") {
// Invalid empty name.
return name;
}
if (name[0] == '/') {
subfile->_name = name.get_fullpath().substr(1);
} else {
subfile->_name = name;
}
pair<Subfiles::iterator, bool> insert_result = _subfiles.insert(subfile);
if (!insert_result.second) {
// Hmm, unable to insert. There must already be a subfile by that
@ -949,7 +968,7 @@ add_new_subfile(Subfile *subfile) {
}
_new_subfiles.push_back(subfile);
return true;
return subfile->_name;
}
////////////////////////////////////////////////////////////////////
@ -1031,7 +1050,7 @@ read_index() {
_last_index = 0;
streampos index_forward;
Subfile *subfile = new Subfile("");
Subfile *subfile = new Subfile;
index_forward = subfile->read_index(*_read, _next_index, this);
while (index_forward != (streampos)0) {
_last_index = _next_index;
@ -1049,7 +1068,7 @@ read_index() {
}
_read->seekg(index_forward);
_next_index = index_forward;
subfile = new Subfile("");
subfile = new Subfile;
index_forward = subfile->read_index(*_read, _next_index, this);
}
if (subfile->is_index_invalid()) {

View File

@ -57,7 +57,7 @@ PUBLISHED:
void set_scale_factor(size_t scale_factor);
INLINE size_t get_scale_factor() const;
bool add_subfile(const string &subfile_name, const Filename &filename);
string add_subfile(const string &subfile_name, const Filename &filename);
bool flush();
bool repack();
@ -81,7 +81,7 @@ public:
bool open_read(istream *multifile_stream);
bool open_write(ostream *multifile_stream);
bool open_read_write(iostream *multifile_stream);
bool add_subfile(const string &subfile_name, istream *subfile_data);
string add_subfile(const string &subfile_name, istream *subfile_data);
bool extract_subfile_to(int index, ostream &out);
istream *open_read_subfile(int index);
@ -95,7 +95,7 @@ private:
class Subfile {
public:
INLINE Subfile(const string &name);
INLINE Subfile();
INLINE bool operator < (const Subfile &other) const;
streampos read_index(istream &read, streampos fpos,
Multifile *multfile);
@ -122,7 +122,7 @@ private:
INLINE streampos normalize_streampos(streampos fpos) const;
streampos pad_to_streampos(streampos fpos);
bool add_new_subfile(Subfile *subfile);
string add_new_subfile(const string &subfile_name, Subfile *subfile);
void clear_subfiles();
bool read_index();
bool write_header();

View File

@ -19,6 +19,7 @@
#include "texturePool.h"
#include "config_gobj.h"
#include "config_util.h"
#include "virtualFileSystem.h"
TexturePool *TexturePool::_global_ptr = (TexturePool *)NULL;
@ -35,8 +36,15 @@ ns_has_texture(Filename filename) {
filename = fake_texture_image;
}
filename.resolve_filename(get_texture_path());
filename.resolve_filename(get_model_path());
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
vfs->resolve_filename(filename, get_texture_path());
vfs->resolve_filename(filename, get_model_path());
} else {
filename.resolve_filename(get_texture_path());
filename.resolve_filename(get_model_path());
}
Textures::const_iterator ti;
ti = _textures.find(filename);
@ -59,8 +67,15 @@ ns_load_texture(Filename filename) {
filename = fake_texture_image;
}
filename.resolve_filename(get_texture_path());
filename.resolve_filename(get_model_path());
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
vfs->resolve_filename(filename, get_texture_path());
vfs->resolve_filename(filename, get_model_path());
} else {
filename.resolve_filename(get_texture_path());
filename.resolve_filename(get_model_path());
}
Textures::const_iterator ti;
ti = _textures.find(filename);
@ -93,11 +108,21 @@ ns_load_texture(Filename filename, Filename grayfilename) {
return ns_load_texture(fake_texture_image);
}
filename.resolve_filename(get_texture_path());
filename.resolve_filename(get_model_path());
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
vfs->resolve_filename(filename, get_texture_path());
vfs->resolve_filename(filename, get_model_path());
grayfilename.resolve_filename(get_texture_path());
grayfilename.resolve_filename(get_model_path());
vfs->resolve_filename(grayfilename, get_texture_path());
vfs->resolve_filename(grayfilename, get_model_path());
} else {
filename.resolve_filename(get_texture_path());
filename.resolve_filename(get_model_path());
grayfilename.resolve_filename(get_texture_path());
grayfilename.resolve_filename(get_model_path());
}
Textures::const_iterator ti;
ti = _textures.find(filename);

View File

@ -24,6 +24,7 @@
#include "bamReader.h"
#include "bamWriter.h"
#include "filename.h"
#include "virtualFileSystem.h"
////////////////////////////////////////////////////////////////////
// Function: BamFile::Constructor
@ -58,11 +59,21 @@ open_read(const Filename &filename, bool report_errors) {
Filename bam_filename(filename);
if (!bam_filename.exists()) {
if (report_errors) {
loader_cat.error() << "Could not find " << bam_filename << "\n";
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
if (!vfs->exists(bam_filename)) {
if (report_errors) {
loader_cat.error() << "Could not find " << bam_filename << "\n";
}
return false;
}
} else {
if (!bam_filename.exists()) {
if (report_errors) {
loader_cat.error() << "Could not find " << bam_filename << "\n";
}
return false;
}
return false;
}
loader_cat.info() << "Reading " << bam_filename << "\n";

View File

@ -21,6 +21,8 @@
#include "loaderFileTypeRegistry.h"
#include "config_pgraph.h"
#include "config_util.h"
#include "virtualFileSystem.h"
#include "event.h"
#include "pt_Event.h"
#include "throw_event.h"
@ -370,6 +372,8 @@ load_unknown_file_type(const Filename &filename) const {
return (PandaNode *)NULL;
}
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
for (int i = 0; i < num_types; i++) {
LoaderConsiderFile consider;
consider._type = reg->get_type(i);
@ -381,8 +385,14 @@ load_unknown_file_type(const Filename &filename) const {
consider._type->resolve_filename(consider._path);
}
if (consider._path.exists()) {
files.push_back(consider);
if (use_vfs) {
if (vfs->exists(consider._path)) {
files.push_back(consider);
}
} else {
if (consider._path.exists()) {
files.push_back(consider);
}
}
}
@ -456,6 +466,8 @@ resolve_unknown_file_type(Filename &filename) const {
return;
}
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
for (int i = 0; i < num_types; i++) {
LoaderConsiderFile consider;
consider._type = reg->get_type(i);
@ -467,8 +479,14 @@ resolve_unknown_file_type(Filename &filename) const {
consider._type->resolve_filename(consider._path);
}
if (consider._path.exists()) {
files.push_back(consider);
if (use_vfs) {
if (vfs->exists(consider._path)) {
files.push_back(consider);
}
} else {
if (consider._path.exists()) {
files.push_back(consider);
}
}
}

View File

@ -20,6 +20,7 @@
#include "config_pgraph.h"
#include "bamFile.h"
#include "virtualFileSystem.h"
#include "config_util.h"
#include "dcast.h"
@ -63,8 +64,14 @@ get_extension() const {
////////////////////////////////////////////////////////////////////
void LoaderFileTypeBam::
resolve_filename(Filename &path) const {
path.resolve_filename(get_bam_path());
path.resolve_filename(get_model_path());
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
vfs->resolve_filename(path, get_bam_path());
vfs->resolve_filename(path, get_model_path());
} else {
path.resolve_filename(get_bam_path());
path.resolve_filename(get_model_path());
}
}
////////////////////////////////////////////////////////////////////

View File

@ -20,6 +20,8 @@
cycleData.h cycleData.I \
cycleDataReader.h cycleDataReader.I \
cycleDataWriter.h cycleDataWriter.I \
datagramInputFile.I datagramInputFile.h \
datagramOutputFile.I datagramOutputFile.h \
drawMask.h \
factoryBase.I factoryBase.h \
factoryParam.I factoryParam.h factoryParams.I \
@ -64,6 +66,7 @@
cycleData.cxx \
cycleDataReader.cxx \
cycleDataWriter.cxx \
datagramInputFile.cxx datagramOutputFile.cxx \
factoryBase.cxx \
factoryParam.cxx factoryParams.cxx globPattern.cxx \
globalPointerRegistry.cxx ioPtaDatagramFloat.cxx \
@ -99,6 +102,8 @@
cycleData.h cycleData.I \
cycleDataReader.h cycleDataReader.I \
cycleDataWriter.h cycleDataWriter.I \
datagramInputFile.I datagramInputFile.h \
datagramOutputFile.I datagramOutputFile.h \
drawMask.h \
factoryBase.I factoryBase.h factoryParam.I factoryParam.h \
factoryParams.I factoryParams.h \

View File

@ -100,3 +100,9 @@ get_sound_path() {
static DSearchPath *sound_path = NULL;
return get_config_path("sound-path", sound_path);
}
// Set this true to use the VirtualFileSystem mechanism for loading
// models, etc. Since the VirtualFileSystem maps to the same as the
// actual file system by default, there is probably no reason to set
// this false, except for testing or if you mistrust the new code.
const bool use_vfs = config_util.GetBool("use-vfs", false);

View File

@ -46,4 +46,6 @@ EXPCL_PANDA DSearchPath &get_texture_path();
EXPCL_PANDA DSearchPath &get_sound_path();
END_PUBLISH
extern EXPCL_PANDA const bool use_vfs;
#endif /* __CONFIG_UTIL_H__ */

View File

@ -26,21 +26,8 @@ INLINE DatagramInputFile::
DatagramInputFile() {
_error = true;
_read_first_datagram = false;
}
////////////////////////////////////////////////////////////////////
// Function: DatagramInputFile::open
// Access: Public
// Description: Opens the indicated filename for reading. Returns
// true if successful, false on failure.
////////////////////////////////////////////////////////////////////
INLINE bool DatagramInputFile::
open(Filename filename) {
// DatagramInputFiles are always binary.
_read_first_datagram = false;
_error = false;
filename.set_binary();
return filename.open_read(_in);
_in = (istream *)NULL;
_owns_in = false;
}
////////////////////////////////////////////////////////////////////
@ -51,5 +38,10 @@ open(Filename filename) {
////////////////////////////////////////////////////////////////////
INLINE void DatagramInputFile::
close() {
_in.close();
_in_file.close();
if (_owns_in) {
delete _in;
_in = (istream *)NULL;
_owns_in = false;
}
}

View File

@ -20,6 +20,8 @@
#include "numeric_types.h"
#include "datagramIterator.h"
#include "profileTimer.h"
#include "config_util.h"
#include "virtualFileSystem.h"
#include "datagramInputFile.h"
@ -28,6 +30,37 @@
EXPCL_PANDAEXPRESS ProfileTimer Skyler_timer_file;
#endif //]
////////////////////////////////////////////////////////////////////
// Function: DatagramInputFile::open
// Access: Public
// Description: Opens the indicated filename for reading. Returns
// true if successful, false on failure.
////////////////////////////////////////////////////////////////////
bool DatagramInputFile::
open(Filename filename) {
// DatagramInputFiles are always binary.
_read_first_datagram = false;
_error = false;
filename.set_binary();
if (use_vfs) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
PT(VirtualFile) file = vfs->get_file(filename);
if (file == (VirtualFile *)NULL) {
// No such file.
return false;
}
_in = file->open_read_file();
_owns_in = (_in != (istream *)NULL);
return _owns_in && !_in->fail();
} else {
_in = &_in_file;
_owns_in = false;
return filename.open_read(_in_file);
}
}
////////////////////////////////////////////////////////////////////
// Function: DatagramInputFile::read_header
// Access: Public
@ -44,8 +77,8 @@ read_header(string &header, size_t num_bytes) {
char *buffer = (char *)alloca(num_bytes);
nassertr(buffer != (char *)NULL, false);
_in.read(buffer, num_bytes);
if (_in.fail() || _in.eof()) {
_in->read(buffer, num_bytes);
if (_in->fail() || _in->eof()) {
return false;
}
@ -70,8 +103,8 @@ get_datagram(Datagram &data) {
// First, get the size of the upcoming datagram. We do this with
// the help of a second datagram.
char sizebuf[sizeof(PN_uint32)];
_in.read(sizebuf, sizeof(PN_uint32));
if (_in.fail() || _in.eof()) {
_in->read(sizebuf, sizeof(PN_uint32));
if (_in->fail() || _in->eof()) {
#ifdef SKYLER_TIMER //[
Skyler_timer_file.off("DatagramInputFile::get_datagram");
#endif //]
@ -86,8 +119,8 @@ get_datagram(Datagram &data) {
char *buffer = new char[num_bytes];
nassertr(buffer != (char *)NULL, false);
_in.read(buffer, num_bytes);
if (_in.fail() || _in.eof()) {
_in->read(buffer, num_bytes);
if (_in->fail() || _in->eof()) {
_error = true;
delete[] buffer;
#ifdef SKYLER_TIMER //[
@ -113,7 +146,7 @@ get_datagram(Datagram &data) {
////////////////////////////////////////////////////////////////////
bool DatagramInputFile::
is_eof() {
return _in.eof();
return _in->eof();
}
////////////////////////////////////////////////////////////////////
@ -124,7 +157,7 @@ is_eof() {
////////////////////////////////////////////////////////////////////
bool DatagramInputFile::
is_error() {
if (_in.fail()) {
if (_in->fail()) {
_error = true;
}
return _error;

View File

@ -34,7 +34,7 @@ class EXPCL_PANDAEXPRESS DatagramInputFile : public DatagramGenerator {
public:
INLINE DatagramInputFile();
INLINE bool open(Filename filename);
bool open(Filename filename);
bool read_header(string &header, size_t num_bytes);
virtual bool get_datagram(Datagram &data);
@ -46,7 +46,9 @@ public:
private:
bool _read_first_datagram;
bool _error;
ifstream _in;
ifstream _in_file;
istream *_in;
bool _owns_in;
};
#include "datagramInputFile.I"

View File

@ -11,6 +11,8 @@
#include "cycleData.cxx"
#include "cycleDataReader.cxx"
#include "cycleDataWriter.cxx"
#include "datagramInputFile.cxx"
#include "datagramOutputFile.cxx"
#include "factoryBase.cxx"
#include "factoryParam.cxx"
#include "factoryParams.cxx"

View File

@ -165,7 +165,7 @@ ls(ostream &out) const {
CPT(VirtualFileList) contents = scan_directory();
if (contents == NULL) {
if (!is_directory()) {
out << get_filename() << " is not a directory.\n";
out << get_filename() << "\n";
} else {
out << get_filename() << " cannot be read.\n";
}

View File

@ -68,6 +68,7 @@ is_regular_file(const Filename &file) const {
istream *VirtualFileMountSystem::
open_read_file(const Filename &file) const {
Filename pathname(_physical_filename, file);
pathname.set_binary();
ifstream *stream = new ifstream;
if (!pathname.open_read(*stream)) {
// Couldn't open the file for some reason.

View File

@ -15,3 +15,112 @@
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::exists
// Access: Published
// Description: Convenience function; returns true if the named file
// exists.
////////////////////////////////////////////////////////////////////
INLINE bool VirtualFileSystem::
exists(const Filename &filename) const {
return get_file(filename) != (VirtualFile *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::is_directory
// Access: Published
// Description: Convenience function; returns true if the named file
// exists and is a directory.
////////////////////////////////////////////////////////////////////
INLINE bool VirtualFileSystem::
is_directory(const Filename &filename) const {
PT(VirtualFile) file = get_file(filename);
return (file != (VirtualFile *)NULL && file->is_directory());
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::is_regular_file
// Access: Published
// Description: Convenience function; returns true if the named file
// exists and is a regular file.
////////////////////////////////////////////////////////////////////
INLINE bool VirtualFileSystem::
is_regular_file(const Filename &filename) const {
PT(VirtualFile) file = get_file(filename);
return (file != (VirtualFile *)NULL && file->is_regular_file());
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::read_file
// Access: Published
// Description: Convenience function; fills the datagram up with the
// data from the indicated file, if it exists and can be
// read. Returns true on success, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool VirtualFileSystem::
read_file(const Filename &filename, Datagram &data) const {
PT(VirtualFile) file = get_file(filename);
return (file != (VirtualFile *)NULL && file->read_file(data));
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::open_read_file
// Access: Published
// Description: Convenience function; returns a newly allocated
// istream if the file exists and can be read, or NULL
// otherwise. Does not return an invalid istream.
////////////////////////////////////////////////////////////////////
INLINE istream *VirtualFileSystem::
open_read_file(const Filename &filename) const {
PT(VirtualFile) file = get_file(filename);
if (file == (VirtualFile *)NULL) {
return NULL;
}
istream *str = file->open_read_file();
if (str != (istream *)NULL && str->fail()) {
delete str;
str = (istream *)NULL;
}
return str;
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::ls
// Access: Published
// Description: Convenience function; lists the files within the
// indicated directory. This accepts a string instead
// of a Filename purely for programmer convenience at
// the Python prompt.
////////////////////////////////////////////////////////////////////
INLINE void VirtualFileSystem::
ls(const string &filename) const {
PT(VirtualFile) file = get_file(filename);
if (file == (VirtualFile *)NULL) {
util_cat.info()
<< "Not found: " << filename << "\n";
} else {
file->ls();
}
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::ls_all
// Access: Published
// Description: Convenience function; lists the files within the
// indicated directory, and all files below,
// recursively. This accepts a string instead of a
// Filename purely for programmer convenience at the
// Python prompt.
////////////////////////////////////////////////////////////////////
INLINE void VirtualFileSystem::
ls_all(const string &filename) const {
PT(VirtualFile) file = get_file(filename);
if (file == (VirtualFile *)NULL) {
util_cat.info()
<< "Not found: " << filename << "\n";
} else {
file->ls_all();
}
}

View File

@ -22,6 +22,8 @@
#include "virtualFileMountSystem.h"
#include "dSearchPath.h"
#include "dcast.h"
#include "config_util.h"
#include "executionEnvironment.h"
VirtualFileSystem *VirtualFileSystem::_global_ptr = NULL;
@ -239,9 +241,12 @@ unmount_all() {
// resolve relative pathnames in get_file() and/or
// find_file(). Returns true if successful, false
// otherwise.
//
// This accepts a string rather than a Filename simply
// for programmer convenience from the Python prompt.
////////////////////////////////////////////////////////////////////
bool VirtualFileSystem::
chdir(const Filename &new_directory) {
chdir(const string &new_directory) {
if (new_directory == "/") {
// We can always return to the root.
_cwd = new_directory;
@ -274,11 +279,11 @@ get_cwd() const {
// 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);
get_file(const Filename &filename) const {
nassertr(!filename.empty(), NULL);
Filename pathname(filename);
if (pathname.is_local()) {
pathname = Filename(_cwd, file);
pathname = Filename(_cwd, filename);
}
pathname.standardize();
string strpath = pathname.get_fullpath().substr(1);
@ -333,14 +338,14 @@ get_file(const Filename &file) const {
// found.
////////////////////////////////////////////////////////////////////
PT(VirtualFile) VirtualFileSystem::
find_file(const Filename &file, const DSearchPath &searchpath) const {
if (file.is_local()) {
return get_file(file);
find_file(const Filename &filename, const DSearchPath &searchpath) const {
if (!filename.is_local()) {
return get_file(filename);
}
int num_directories = searchpath.get_num_directories();
for (int i = 0; i < num_directories; i++) {
Filename match(searchpath.get_directory(i), file);
Filename match(searchpath.get_directory(i), filename);
PT(VirtualFile) found_file = get_file(match);
if (found_file != (VirtualFile *)NULL) {
return found_file;
@ -350,6 +355,58 @@ find_file(const Filename &file, const DSearchPath &searchpath) const {
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::resolve_filename
// Access: Public
// Description: Searches the given search path for the filename. If
// it is found, updates the filename to the full
// pathname found and returns true; otherwise, returns
// false.
////////////////////////////////////////////////////////////////////
bool VirtualFileSystem::
resolve_filename(Filename &filename,
const DSearchPath &searchpath,
const string &default_extension) const {
PT(VirtualFile) found;
if (filename.is_local()) {
found = find_file(filename.get_fullpath(), searchpath);
if (found.is_null()) {
// We didn't find it with the given extension; can we try the
// default extension?
if (filename.get_extension().empty() && !default_extension.empty()) {
Filename try_ext = filename;
try_ext.set_extension(default_extension);
found = find_file(try_ext.get_fullpath(), searchpath);
}
}
} else {
if (exists(filename)) {
// The full pathname exists. Return true.
return true;
} else {
// The full pathname doesn't exist with the given extension;
// does it exist with the default extension?
if (filename.get_extension().empty() && !default_extension.empty()) {
Filename try_ext = filename;
try_ext.set_extension(default_extension);
found = get_file(try_ext);
}
}
}
if (!found.is_null()) {
filename = found->get_filename();
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::write
// Access: Published
@ -383,7 +440,34 @@ VirtualFileSystem *VirtualFileSystem::
get_global_ptr() {
if (_global_ptr == (VirtualFileSystem *)NULL) {
_global_ptr = new VirtualFileSystem;
// Set up the default mounts. First, there is always the root
// mount.
_global_ptr->mount("/", "/", 0);
// Then, we add whatever mounts are listed in the Configrc file.
Config::ConfigTable::Symbol mounts;
config_util.GetAll("vfs-mount", mounts);
Config::ConfigTable::Symbol::iterator si;
for (si = mounts.begin(); si != mounts.end(); ++si) {
string mount_desc = (*si).Val();
// The last space marks the beginning of the mount point.
// Spaces before that are part of the system filename.
size_t space = mount_desc.rfind(' ');
if (space == string::npos) {
util_cat.warning()
<< "No space in vfs-mount descriptor: " << mount_desc << "\n";
} else {
string fn = trim_right(mount_desc.substr(0, space));
fn = ExecutionEnvironment::expand_string(fn);
Filename physical_filename = Filename::from_os_specific(fn);
string mount_point = mount_desc.substr(space + 1);
_global_ptr->mount(physical_filename, mount_point, 0);
}
}
}
return _global_ptr;

View File

@ -21,11 +21,15 @@
#include "pandabase.h"
#include "virtualFile.h"
#include "filename.h"
#include "pointerTo.h"
#include "pmap.h"
#include "config_util.h"
class Multifile;
class VirtualFileMount;
class VirtualFileComposite;
////////////////////////////////////////////////////////////////////
// Class : VirtualFileSystem
@ -55,12 +59,25 @@ PUBLISHED:
int unmount_point(const string &mount_point);
int unmount_all();
bool chdir(const Filename &new_directory);
bool chdir(const string &new_directory);
const Filename &get_cwd() const;
PT(VirtualFile) get_file(const Filename &file) const;
PT(VirtualFile) find_file(const Filename &file,
PT(VirtualFile) get_file(const Filename &filename) const;
PT(VirtualFile) find_file(const Filename &filename,
const DSearchPath &searchpath) const;
bool resolve_filename(Filename &filename,
const DSearchPath &searchpath,
const string &default_extension = string()) const;
INLINE bool exists(const Filename &filename) const;
INLINE bool is_directory(const Filename &filename) const;
INLINE bool is_regular_file(const Filename &filename) const;
INLINE bool read_file(const Filename &filename, Datagram &data) const;
INLINE istream *open_read_file(const Filename &filename) const;
INLINE void ls(const string &filename) const;
INLINE void ls_all(const string &filename) const;
void write(ostream &out) const;