Added support for master file and clean up Archive API.

This commit is contained in:
Robert Osfield
2004-11-10 13:03:52 +00:00
parent 1772c9daa5
commit 4e19c03de1
3 changed files with 148 additions and 89 deletions

View File

@@ -24,35 +24,6 @@
int main( int argc, char **argv )
{
/*
std::fstream fout("test.data",std::ofstream::out | std::ofstream::binary);
unsigned int numCharacters = 26;
char baseCharacter = 'A';
for(unsigned int i=0;i<numCharacters;++i)
{
char c = baseCharacter + i;
fout.write(&c,1);
}
fout.close();
fout.open("test.data",std::ofstream::out | std::ofstream::in | std::ofstream::binary);
char offset = 'a'-'A';
unsigned int start_range = 5;
unsigned int end_range = 15;
fout.seekp(start_range);
for(unsigned int i=start_range;i<end_range;++i)
{
char c = (baseCharacter + i)+offset ;
fout.write(&c,1);
}
fout.close();
*/
// use an ArgumentParser object to manage the program arguments.
osg::ArgumentParser arguments(&argc,argv);
@@ -189,14 +160,19 @@ int main( int argc, char **argv )
if (list)
{
std::cout<<"List of files in archive:"<<std::endl;
const osgDB::Archive::FileNamePositionMap& indexMap = archive.getFileNamePositionMap();
for(osgDB::Archive::FileNamePositionMap::const_iterator itr=indexMap.begin();
itr!=indexMap.end();
++itr)
osgDB::Archive::FileNameList fileNames;
if (archive.getFileNames(fileNames))
{
std::cout<<" "<<itr->first<<"\t"<<itr->second.first<<"\t"<<itr->second.second<<std::endl;
for(osgDB::Archive::FileNameList::const_iterator itr=fileNames.begin();
itr!=fileNames.end();
++itr)
{
std::cout<<" "<<*itr<<std::endl;
}
}
std::cout<<std::endl;
std::cout<<"Master file "<<archive.getMasterFileName()<<std::endl;
}
return 0;

View File

@@ -45,54 +45,47 @@ class OSGDB_EXPORT Archive : public ReaderWriter
/** return true if file exists in archive.*/
virtual bool fileExists(const std::string& filename) const;
typedef std::istream::pos_type pos_type;
typedef std::istream::off_type size_type;
typedef std::pair<pos_type, size_type> PositionSizePair;
typedef std::map<std::string, PositionSizePair> FileNamePositionMap;
/** Get the file name which represents the master file recorded in the Archive.*/
virtual std::string getMasterFileName() const;
typedef std::vector<std::string> FileNameList;
/** Get the full list of file names available in the archive.*/
virtual bool getFileNames(FileNameList& fileNameList) const;
const FileNamePositionMap& getFileNamePositionMap() const { return _indexMap; }
/** Read an osg::Object of specified file name from the Archive.*/
virtual ReadResult readObject(const std::string& fileName,const Options* options=NULL);
/** Read an osg::Image of specified file name from the Archive.*/
virtual ReadResult readImage(const std::string& fileName,const Options* options=NULL);
/** Read an osg::HeightField of specified file name from the Archive.*/
virtual ReadResult readHeightField(const std::string& fileName,const Options* options=NULL);
/** Read an osg::Node of specified file name from the Archive.*/
virtual ReadResult readNode(const std::string& fileName,const Options* options=NULL);
/** Write an osg::Object with specified file name to the Archive.*/
virtual WriteResult writeObject(const osg::Object& obj,const std::string& fileName,const Options* options=NULL);
/** Write an osg::Image with specified file name to the Archive.*/
virtual WriteResult writeImage(const osg::Image& image,const std::string& fileName,const Options* options=NULL);
/** Write an osg::HeightField with specified file name to the Archive.*/
virtual WriteResult writeHeightField(const osg::HeightField& heightField,const std::string& fileName,const Options* options=NULL);
/** Write an osg::Node with specified file name to the Archive.*/
virtual WriteResult writeNode(const osg::Node& node,const std::string& fileName,const Options* options=NULL);
/** Functor used in internal implementations.*/
struct ReadFunctor
{
ReadFunctor(const std::string& filename, const ReaderWriter::Options* options):
_filename(filename),
_options(options) {}
virtual ~ReadFunctor() {}
virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const = 0;
std::string _filename;
const ReaderWriter::Options* _options;
};
/** Functor used in internal implementations.*/
struct WriteFunctor
{
WriteFunctor(const std::string& filename, const ReaderWriter::Options* options):
_filename(filename),
_options(options) {}
virtual ~WriteFunctor() {}
virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const = 0;
std::string _filename;
const ReaderWriter::Options* _options;
};
protected:
typedef std::istream::pos_type pos_type;
typedef std::istream::off_type size_type;
typedef std::pair<pos_type, size_type> PositionSizePair;
typedef std::map<std::string, PositionSizePair> FileNamePositionMap;
class IndexBlock : public osg::Referenced
{
@@ -111,7 +104,9 @@ class OSGDB_EXPORT Archive : public ReaderWriter
static IndexBlock* read(std::istream& in);
bool getFileReferences(FileNamePositionMap& indexMap);
std::string getFirstFileName() const;
bool getFileReferences(FileNamePositionMap& indexMap) const;
inline bool requiresWrite() const { return _requiresWrite; }
@@ -142,6 +137,45 @@ class OSGDB_EXPORT Archive : public ReaderWriter
char* _data;
};
/** Functor used in internal implementations.*/
struct ReadFunctor
{
ReadFunctor(const std::string& filename, const ReaderWriter::Options* options):
_filename(filename),
_options(options) {}
virtual ~ReadFunctor() {}
virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const = 0;
std::string _filename;
const ReaderWriter::Options* _options;
};
struct ReadObjectFunctor;
struct ReadImageFunctor;
struct ReadHeightFieldFunctor;
struct ReadNodeFunctor;
/** Functor used in internal implementations.*/
struct WriteFunctor
{
WriteFunctor(const std::string& filename, const ReaderWriter::Options* options):
_filename(filename),
_options(options) {}
virtual ~WriteFunctor() {}
virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const = 0;
std::string _filename;
const ReaderWriter::Options* _options;
};
struct WriteObjectFunctor;
struct WriteImageFunctor;
struct WriteHeightFieldFunctor;
struct WriteNodeFunctor;
ReaderWriter::ReadResult read(const ReadFunctor& readFunctor);
ReaderWriter::WriteResult write(const WriteFunctor& writeFunctor);
@@ -157,6 +191,7 @@ class OSGDB_EXPORT Archive : public ReaderWriter
std::ifstream _input;
std::fstream _output;
std::string _masterFileName;
IndexBlockList _indexBlockList;
FileNamePositionMap _indexMap;

View File

@@ -17,6 +17,8 @@
#include <osgDB/FileNameUtils>
#include <osgDB/Archive>
#include <streambuf>
using namespace osgDB;
float Archive::s_currentSupportedVersion = 0.0;
@@ -91,7 +93,27 @@ Archive::IndexBlock* Archive::IndexBlock::read(std::istream& in)
}
bool Archive::IndexBlock::getFileReferences(FileNamePositionMap& indexMap)
std::string Archive::IndexBlock::getFirstFileName() const
{
char* ptr = _data;
char* end_ptr = _data + _offsetOfNextAvailableSpace;
if (ptr<end_ptr)
{
ptr += sizeof(pos_type);
ptr += sizeof(size_type);
unsigned int filename_size = *(reinterpret_cast<unsigned int*>(ptr));
ptr += sizeof(unsigned int);
return std::string(ptr, ptr+filename_size);
}
else
{
return std::string();
}
}
bool Archive::IndexBlock::getFileReferences(FileNamePositionMap& indexMap) const
{
if (!_data || _offsetOfNextAvailableSpace==0) return false;
@@ -194,7 +216,6 @@ Archive::~Archive()
{
close();
}
#include <sys/stat.h>
bool Archive::open(const std::string& filename, ArchiveStatus status, unsigned int indexBlockSize)
{
@@ -229,6 +250,12 @@ bool Archive::open(const std::string& filename, ArchiveStatus status, unsigned i
// now need to build the filename map.
_indexMap.clear();
if (!_indexBlockList.empty())
{
_masterFileName = _indexBlockList.front()->getFirstFileName();
}
for(IndexBlockList::iterator itr=_indexBlockList.begin();
itr!=_indexBlockList.end();
++itr)
@@ -321,6 +348,25 @@ void Archive::close()
}
}
std::string Archive::getMasterFileName() const
{
return _masterFileName;
}
bool Archive::getFileNames(FileNameList& fileNameList) const
{
fileNameList.clear();
fileNameList.reserve(_indexMap.size());
for(FileNamePositionMap::const_iterator itr=_indexMap.begin();
itr!=_indexMap.end();
++itr)
{
fileNameList.push_back(itr->first);
}
return !fileNameList.empty();
}
void Archive::writeIndexBlocks()
{
if (_status==WRITE)
@@ -356,6 +402,11 @@ bool Archive::addFileReference(pos_type position, size_type size, const std::str
return false;
}
// if the masterFileName isn't set yet use this fileName
if (_masterFileName.empty()) _masterFileName = fileName;
// get an IndexBlock with space available if possible
unsigned int blockSize = 4096;
osg::ref_ptr<IndexBlock> indexBlock = _indexBlockList.empty() ? 0 : _indexBlockList.back();
@@ -388,7 +439,6 @@ bool Archive::addFileReference(pos_type position, size_type size, const std::str
}
#include <streambuf>
class proxy_streambuf : public std::streambuf
{
@@ -434,27 +484,27 @@ class proxy_streambuf : public std::streambuf
}
};
struct ArchiveReadObjectFunctor : public Archive::ReadFunctor
struct Archive::ReadObjectFunctor : public Archive::ReadFunctor
{
ArchiveReadObjectFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {}
ReadObjectFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {}
virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const { return rw.readObject(input, _options); }
};
struct ArchiveReadImageFunctor : public Archive::ReadFunctor
struct Archive::ReadImageFunctor : public Archive::ReadFunctor
{
ArchiveReadImageFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {}
ReadImageFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {}
virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input)const { return rw.readImage(input, _options); }
};
struct ArchiveReadHeightFieldFunctor : public Archive::ReadFunctor
struct Archive::ReadHeightFieldFunctor : public Archive::ReadFunctor
{
ArchiveReadHeightFieldFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {}
ReadHeightFieldFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {}
virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const { return rw.readHeightField(input, _options); }
};
struct ArchiveReadNodeFunctor : public Archive::ReadFunctor
struct Archive::ReadNodeFunctor : public Archive::ReadFunctor
{
ArchiveReadNodeFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {}
ReadNodeFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {}
virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const { return rw.readNode(input, _options); }
};
@@ -498,28 +548,26 @@ ReaderWriter::ReadResult Archive::read(const ReadFunctor& readFunctor)
ReaderWriter::ReadResult Archive::readObject(const std::string& fileName,const Options* options)
{
return read(ArchiveReadObjectFunctor(fileName, options));
return read(ReadObjectFunctor(fileName, options));
}
ReaderWriter::ReadResult Archive::readImage(const std::string& fileName,const Options* options)
{
return read(ArchiveReadImageFunctor(fileName, options));
return read(ReadImageFunctor(fileName, options));
}
ReaderWriter::ReadResult Archive::readHeightField(const std::string& fileName,const Options* options)
{
return read(ArchiveReadHeightFieldFunctor(fileName, options));
return read(ReadHeightFieldFunctor(fileName, options));
}
ReaderWriter::ReadResult Archive::readNode(const std::string& fileName,const Options* options)
{
return read(ArchiveReadNodeFunctor(fileName, options));
return read(ReadNodeFunctor(fileName, options));
}
struct WriteObjectFunctor : public Archive::WriteFunctor
struct Archive::WriteObjectFunctor : public Archive::WriteFunctor
{
WriteObjectFunctor(const osg::Object& object, const std::string& filename, const ReaderWriter::Options* options):
WriteFunctor(filename,options),
@@ -529,7 +577,7 @@ struct WriteObjectFunctor : public Archive::WriteFunctor
virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const { return rw.writeObject(_object, output, _options); }
};
struct WriteImageFunctor : public Archive::WriteFunctor
struct Archive::WriteImageFunctor : public Archive::WriteFunctor
{
WriteImageFunctor(const osg::Image& object, const std::string& filename, const ReaderWriter::Options* options):
WriteFunctor(filename,options),
@@ -539,7 +587,7 @@ struct WriteImageFunctor : public Archive::WriteFunctor
virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output)const { return rw.writeImage(_object, output, _options); }
};
struct WriteHeightFieldFunctor : public Archive::WriteFunctor
struct Archive::WriteHeightFieldFunctor : public Archive::WriteFunctor
{
WriteHeightFieldFunctor(const osg::HeightField& object, const std::string& filename, const ReaderWriter::Options* options):
WriteFunctor(filename,options),
@@ -549,7 +597,7 @@ struct WriteHeightFieldFunctor : public Archive::WriteFunctor
virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const { return rw.writeHeightField(_object, output, _options); }
};
struct WriteNodeFunctor : public Archive::WriteFunctor
struct Archive::WriteNodeFunctor : public Archive::WriteFunctor
{
WriteNodeFunctor(const osg::Node& object, const std::string& filename, const ReaderWriter::Options* options):
WriteFunctor(filename,options),