Added prelimanary prox stream buffer to fake the ending of file.

This commit is contained in:
Robert Osfield 2004-11-02 17:05:15 +00:00
parent fae2416584
commit ffca165611
3 changed files with 87 additions and 43 deletions

View File

@ -9,6 +9,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <osg/Timer>
#include <osg/ArgumentParser>
#include <osg/ApplicationUsage>
@ -22,51 +23,38 @@
#include <locale>
#include <cstdio>
template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
class proxy_basic_streambuf : public std::basic_streambuf<_CharT, _Traits>
class proxy_streambuf : public std::streambuf
{
public:
typedef _CharT char_type;
typedef _Traits traits_type;
typedef typename traits_type::int_type int_type;
typedef typename traits_type::pos_type pos_type;
typedef typename traits_type::off_type off_type;
proxy_basic_streambuf(unsigned int numChars):
proxy_streambuf(std::streambuf* streambuf, unsigned int numChars):
_streambuf(streambuf),
_numChars(numChars) {}
/// Destructor deallocates no buffer space.
virtual ~proxy_basic_streambuf() {}
virtual ~proxy_streambuf() {}
std::streambuf* _streambuf;
unsigned int _numChars;
protected:
virtual int_type overflow (int_type __c = traits_type::eof())
virtual int_type uflow ()
{
if (_numChars==0)
{
putchar('E');
return traits_type::eof();
}
if (__c == traits_type::eof()) return '\n'; traits_type::not_eof(__c);
//putchar('');
if (_numChars==0) return -1;
--_numChars;
return putchar(__c);
return _streambuf->sbumpc();
}
};
typedef proxy_basic_streambuf<char> proxy_streambuf;
int main( int argc, char **argv )
{
/*
std::ifstream fin("GNUmakefile");
std::istream& ins = fin;
proxy_streambuf mystreambuf(100);
std::cout.rdbuf(&mystreambuf);
proxy_streambuf mystreambuf(ins.rdbuf(),10000);
ins.rdbuf(&mystreambuf);
while (!fin.eof())
{
@ -74,9 +62,9 @@ int main( int argc, char **argv )
}
std::cout<<"Exiting normally "<<std::endl;
std::cout.rdbuf(0);
ins.rdbuf(mystreambuf._streambuf);
*/
/*
// use an ArgumentParser object to manage the program arguments.
osg::ArgumentParser arguments(&argc,argv);
@ -184,8 +172,10 @@ int main( int argc, char **argv )
itr!=files.end();
++itr)
{
osg::Timer_t start = osg::Timer::instance()->tick();
osgDB::ReaderWriter::ReadResult result = archive.readObject(*itr);
osg::ref_ptr<osg::Object> obj = result.getObject();
std::cout<<"readObejct time = "<<osg::Timer::instance()->delta_m(start,osg::Timer::instance()->tick())<<std::endl;
if (obj.valid())
{
if (obj.valid()) osgDB::writeObjectFile(*obj, *itr);
@ -202,12 +192,11 @@ int main( int argc, char **argv )
itr!=indexMap.end();
++itr)
{
std::cout<<" "<<itr->first<<"\t"<<itr->second<<std::endl;
std::cout<<" "<<itr->first<<"\t"<<itr->second.first<<"\t"<<itr->second.second<<std::endl;
}
}
*/
return 0;
}

View File

@ -56,7 +56,9 @@ class OSGDB_EXPORT Archive : public ReaderWriter
virtual bool fileExists(const std::string& filename) const;
typedef std::istream::pos_type pos_type;
typedef std::map<std::string, pos_type> FileNamePositionMap;
typedef std::istream::off_type size_type;
typedef std::pair<pos_type, size_type> PositionSizePair;
typedef std::map<std::string, PositionSizePair> FileNamePositionMap;
const FileNamePositionMap& getFileNamePositionMap() const { return _indexMap; }
@ -98,13 +100,13 @@ class OSGDB_EXPORT Archive : public ReaderWriter
void write(std::ostream& out);
inline bool spaceAvailable(pos_type position, const std::string& filename) const
inline bool spaceAvailable(pos_type position, size_type size, const std::string& filename) const
{
unsigned requiredSize = sizeof(position)+sizeof(unsigned int)+filename.size();
return (_offsetOfNextAvailableSpace + requiredSize)<_blockSize;
}
bool addFileReference(pos_type position, const std::string& filename);
bool addFileReference(pos_type position, size_type size, const std::string& filename);
@ -128,7 +130,7 @@ class OSGDB_EXPORT Archive : public ReaderWriter
void writeIndexBlocks();
bool addFileReference(pos_type position, const std::string& fileName);
bool addFileReference(pos_type position, size_type size, const std::string& fileName);
static float s_currentSupportedVersion;
float _version;

View File

@ -93,13 +93,16 @@ bool Archive::IndexBlock::getFileReferences(FileNamePositionMap& indexMap)
pos_type position = *(reinterpret_cast<pos_type*>(ptr));
ptr += sizeof(pos_type);
size_type size = *(reinterpret_cast<size_type*>(ptr));
ptr += sizeof(size_type);
unsigned int filename_size = *(reinterpret_cast<unsigned int*>(ptr));
ptr += sizeof(unsigned int);
std::string filename(ptr, ptr+filename_size);
// record this entry into the FileNamePositionMap
indexMap[filename] = position;
indexMap[filename] = PositionSizePair(position,size);
ptr += filename_size;
@ -129,15 +132,18 @@ void Archive::IndexBlock::write(std::ostream& out)
}
bool Archive::IndexBlock::addFileReference(pos_type position, const std::string& filename)
bool Archive::IndexBlock::addFileReference(pos_type position, size_type size, const std::string& filename)
{
if (spaceAvailable(position, filename))
if (spaceAvailable(position, size, filename))
{
unsigned char* ptr = _data+_offsetOfNextAvailableSpace;
*(reinterpret_cast<pos_type*>(ptr)) = position;
ptr += sizeof(pos_type);
*(reinterpret_cast<size_type*>(ptr)) = size;
ptr += sizeof(size_type);
*(reinterpret_cast<unsigned int*>(ptr)) = filename.size();
ptr += sizeof(unsigned int);
@ -236,7 +242,7 @@ bool Archive::open(const std::string& filename, Status status)
mitr!=_indexMap.end();
++mitr)
{
osg::notify(osg::NOTICE)<<" filename "<<(mitr->first)<<" pos="<<(int)(mitr->second)<<std::endl;
osg::notify(osg::NOTICE)<<" filename "<<(mitr->first)<<" pos="<<(int)((mitr->second).first)<<" size="<<(int)((mitr->second).second)<<std::endl;
}
@ -300,7 +306,7 @@ bool Archive::fileExists(const std::string& filename) const
return (_indexMap.count(filename)!=0);
}
bool Archive::addFileReference(pos_type position, const std::string& fileName)
bool Archive::addFileReference(pos_type position, size_type size, const std::string& fileName)
{
if (_status==READ)
{
@ -321,7 +327,7 @@ bool Archive::addFileReference(pos_type position, const std::string& fileName)
if (indexBlock.valid())
{
blockSize = indexBlock->getBlockSize();
if (!(indexBlock->spaceAvailable(position, fileName)))
if (!(indexBlock->spaceAvailable(position, size, fileName)))
{
previousBlock = indexBlock;
indexBlock = 0;
@ -340,12 +346,38 @@ bool Archive::addFileReference(pos_type position, const std::string& fileName)
if (indexBlock.valid())
{
return indexBlock->addFileReference(position, fileName);
return indexBlock->addFileReference(position, size, fileName);
}
return false;
}
#include <streambuf>
class proxy_streambuf : public std::streambuf
{
public:
proxy_streambuf(std::streambuf* streambuf, unsigned int numChars):
_streambuf(streambuf),
_numChars(numChars) {}
/// Destructor deallocates no buffer space.
virtual ~proxy_streambuf() {}
std::streambuf* _streambuf;
unsigned int _numChars;
protected:
virtual int_type uflow ()
{
//if (_numChars==0) return -1;
//--_numChars;
return _streambuf->sbumpc();
}
};
ReaderWriter::ReadResult Archive::readObject(const std::string& fileName,const Options* options)
{
if (_status!=READ)
@ -361,8 +393,6 @@ ReaderWriter::ReadResult Archive::readObject(const std::string& fileName,const O
return ReadResult(ReadResult::FILE_NOT_FOUND);
}
_input.seekg(itr->second);
ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension(getLowerCaseFileExtension(fileName));
if (!rw)
{
@ -371,7 +401,26 @@ ReaderWriter::ReadResult Archive::readObject(const std::string& fileName,const O
}
osg::notify(osg::NOTICE)<<"Archive::readObject(obj, "<<fileName<<")"<<std::endl;
return rw->readObject(_input, options);
_input.seekg(itr->second.first);
std::istream& ins = _input;
proxy_streambuf mystreambuf(ins.rdbuf(),itr->second.second);
ins.rdbuf(&mystreambuf);
/*
while (!_input.eof())
{
osg::notify(osg::NOTICE).put(_input.get());
}
osg::notify(osg::NOTICE)<<"Exiting normally "<<std::endl;
*/
ReaderWriter::ReadResult result = rw->readObject(_input, options);
ins.rdbuf(mystreambuf._streambuf);
return result;
}
ReaderWriter::ReadResult Archive::readImage(const std::string& /*fileName*/,const Options*) { return ReadResult(ReadResult::FILE_NOT_HANDLED); }
@ -381,6 +430,7 @@ ReaderWriter::ReadResult Archive::readNode(const std::string& /*fileName*/,const
ReaderWriter::WriteResult Archive::writeObject(const osg::Object& obj,const std::string& fileName,const Options* options)
{
if (_status!=WRITE)
@ -402,7 +452,10 @@ ReaderWriter::WriteResult Archive::writeObject(const osg::Object& obj,const std:
WriteResult result = rw->writeObject(obj, _output, options);
if (result.success()) addFileReference(position, fileName);
pos_type final_position = _output.tellp();
size_type size = size_type(final_position-position);
if (result.success()) addFileReference(position, size, fileName);
return result;
}