Added support for master file and clean up Archive API.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user