Files
OpenSceneGraph/src/osgPlugins/tgz/ReaderWriterTGZ.cpp
2019-05-14 14:25:30 +02:00

163 lines
5.4 KiB
C++

#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <osg/Geode>
#include <osg/Group>
#include <osg/Notify>
#include <osg/os_utils>
#include <osgDB/ReadFile>
#include <osgDB/FileUtils>
#include <osgDB/FileNameUtils>
#include <osgDB/Registry>
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <direct.h>
#else
#include <unistd.h>
#endif
using namespace osg;
class ReaderWriterTGZ : public osgDB::ReaderWriter
{
public:
virtual const char* className() const { return "TGZ Database Reader/Writer"; }
ReaderWriterTGZ()
{
supportsExtension("tgz","Tar gzip'd archive format");
}
virtual ReadResult readObject(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
{
return readNode(fileName, options);
}
virtual ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const
{
std::string ext = osgDB::getLowerCaseFileExtension(file);
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
OSG_NOTICE<<"file="<<file<<std::endl;
std::string fileName = osgDB::findDataFile( file, options );
OSG_NOTICE<<"fileName="<<fileName<<std::endl;
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
OSG_INFO<< "ReaderWriterTGZ::readNode( "<<fileName.c_str()<<" )\n";
char dirname[128];
char command[1024];
#if defined(_WIN32) && !defined(__CYGWIN__)
if ( getenv("TEMP") != NULL ){
strcpy(dirname, getenv("TEMP"));
}else{
//TEMP environment variable not set so pick current directory.
strcpy(dirname, "./");
}
strcat(dirname, ".osgdb_tgz");
if (mkdir( dirname)!=0)
{
return ReadResult::ERROR_IN_READING_FILE;
}
// Using tar.exe from http://www.cygwin.com/
// tar.exe must be in your path. (PATH environment variable).
sprintf( command,
"tar xfCz \"%s\" \"%s\"",
fileName.c_str(), dirname );
#endif
#if defined(__linux) || defined(__CYGWIN__)
sprintf( dirname, "/tmp/.tgz%06d", getpid());
if (mkdir( dirname, 0700 )!=0)
{
return ReadResult::ERROR_IN_READING_FILE;
}
sprintf( command,
"tar xfCz %s %s",
fileName.c_str(), dirname );
#endif
#ifdef __sgi
sprintf( dirname, "/tmp/.tgz%06d", getpid());
if (mkdir( dirname, 0700 )!=0)
{
return ReadResult::ERROR_IN_READING_FILE;
}
sprintf( command,
"cp %s %s; cd %s;"
"gzcat %s | tar xf -",
fileName.c_str(), dirname, dirname,
fileName.c_str());
#endif
OSG_NOTICE<<"Running command '"<<command<<"'"<<std::endl;
int result = osg_system( command );
if (result!=0) return ReadResult::ERROR_IN_READING_FILE;
osg::ref_ptr<osg::Group> grp = new osg::Group;
OSG_NOTICE<<"Done"<<std::endl;
osg::ref_ptr<osgDB::ReaderWriter::Options> local_options = options ? static_cast<osgDB::ReaderWriter::Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) : new osgDB::ReaderWriter::Options;
local_options->getDatabasePathList().push_front(dirname);
OSG_NOTICE<<"local_options->getDatabasePathList().="<<local_options->getDatabasePathList().front()<<std::endl;
OSG_NOTICE<<"dirname="<<dirname<<std::endl;
// deactivate the automatic generation of images to geode's.
bool prevCreateNodeFromImage = osgDB::Registry::instance()->getCreateNodeFromImage();
osgDB::Registry::instance()->setCreateNodeFromImage(false);
osgDB::DirectoryContents contents = osgDB::getDirectoryContents(dirname);
for(osgDB::DirectoryContents::iterator itr = contents.begin();
itr != contents.end();
++itr)
{
std::string file_ext = osgDB::getFileExtension(*itr);
if (!acceptsExtension(file_ext) &&
*itr!=std::string(".") &&
*itr!=std::string(".."))
{
osg::ref_ptr<osg::Node> node = osgDB::readRefNodeFile(*itr, local_options.get());
if (node) grp->addChild( node );
}
}
// restorre original state of the automatic generation of images to geode's.
osgDB::Registry::instance()->setCreateNodeFromImage(prevCreateNodeFromImage);
#if defined(_WIN32) && !defined(__CYGWIN__)
sprintf( command, "erase /F /Q /S \"%s\"", dirname );
#else
sprintf( command, "rm -rf %s", dirname );
#endif
OSG_NOTICE<<"Running command '"<<command<<"'"<<std::endl;
result = osg_system( command );
if (result!=0) return ReadResult::ERROR_IN_READING_FILE;
if( grp->getNumChildren() == 0 )
{
return ReadResult::FILE_NOT_HANDLED;
}
return grp;
}
};
// now register with sgRegistry to instantiate the above
// reader/writer.
REGISTER_OSGPLUGIN(tgz, ReaderWriterTGZ)