From Bradley Anderegg, "Ok, I am re-submitting this with the changes we discussed. That is, there is a default implementation of osgDB::Archive::getDirectoryContents() that uses getFileNames(), and the osgDB::ArchiveExtended header was removed as it is now unnecessary.
Here is a quick list of the modified files: Archive - getDirectoryContents() no longer pure virtual Archive.cpp - default getDirectoryContents() implementation unzip.cpp - modified to fix a bug where the same file will not load twice in a row ZipArchive.h / ZipArchive.cpp - extends osgDB::Archive and provides support for random access loading within a .zip file ReaderWriterZip.cpp - modified to use the ZipArchive class"
This commit is contained in:
parent
51a9e63c55
commit
76b6cd6fa3
@ -59,7 +59,7 @@ class OSGDB_EXPORT Archive : public ReaderWriter
|
|||||||
|
|
||||||
/** return the contents of a directory.
|
/** return the contents of a directory.
|
||||||
* returns an empty array on any error.*/
|
* returns an empty array on any error.*/
|
||||||
virtual DirectoryContents getDirectoryContents(const std::string& dirName) const = 0;
|
virtual DirectoryContents getDirectoryContents(const std::string& dirName) const;
|
||||||
|
|
||||||
|
|
||||||
virtual ReadResult readObject(const std::string& /*fileName*/,const Options* =NULL) const = 0;
|
virtual ReadResult readObject(const std::string& /*fileName*/,const Options* =NULL) const = 0;
|
||||||
|
@ -50,3 +50,73 @@ Archive::~Archive()
|
|||||||
OSG_INFO<<"Archive::~Archive() closed"<<std::endl;
|
OSG_INFO<<"Archive::~Archive() closed"<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cleanupFileString(std::string& strFileOrDir)
|
||||||
|
{
|
||||||
|
if (strFileOrDir.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert all separators to unix-style for conformity
|
||||||
|
for (unsigned int i = 0; i < strFileOrDir.length(); ++i)
|
||||||
|
{
|
||||||
|
if (strFileOrDir[i] == '\\')
|
||||||
|
{
|
||||||
|
strFileOrDir[i] = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get rid of trailing separators
|
||||||
|
if (strFileOrDir[strFileOrDir.length()-1] == '/')
|
||||||
|
{
|
||||||
|
strFileOrDir = strFileOrDir.substr(0, strFileOrDir.length()-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//add a beginning separator
|
||||||
|
if(strFileOrDir[0] != '/')
|
||||||
|
{
|
||||||
|
strFileOrDir.insert(0, "/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
osgDB::DirectoryContents osgDB::Archive::getDirectoryContents(const std::string& dirName) const
|
||||||
|
{
|
||||||
|
DirectoryContents filenames;
|
||||||
|
getFileNames(filenames);
|
||||||
|
|
||||||
|
std::string searchPath = dirName;
|
||||||
|
cleanupFileString(searchPath);
|
||||||
|
|
||||||
|
osgDB::DirectoryContents dirContents;
|
||||||
|
|
||||||
|
DirectoryContents::const_iterator iter = filenames.begin();
|
||||||
|
DirectoryContents::const_iterator iterEnd = filenames.end();
|
||||||
|
|
||||||
|
for(; iter != iterEnd; ++iter)
|
||||||
|
{
|
||||||
|
std::string currentFile = *iter;
|
||||||
|
|
||||||
|
cleanupFileString(currentFile);
|
||||||
|
|
||||||
|
if(currentFile.size() > searchPath.size())
|
||||||
|
{
|
||||||
|
size_t endSubElement = currentFile.find(searchPath);
|
||||||
|
|
||||||
|
//we match the whole string in the beginning of the path
|
||||||
|
if(endSubElement == 0)
|
||||||
|
{
|
||||||
|
std::string remainingFile = currentFile.substr(searchPath.size() + 1, std::string::npos);
|
||||||
|
size_t endFileToken = remainingFile.find_first_of('/');
|
||||||
|
|
||||||
|
if(endFileToken == std::string::npos)
|
||||||
|
{
|
||||||
|
dirContents.push_back(remainingFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dirContents;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
SET(TARGET_SRC
|
SET(TARGET_SRC
|
||||||
unzip.cpp
|
unzip.cpp
|
||||||
|
ZipArchive.cpp
|
||||||
ReaderWriterZIP.cpp
|
ReaderWriterZIP.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(TARGET_H
|
SET(TARGET_H
|
||||||
unzip.h
|
unzip.h
|
||||||
|
ZipArchive.h
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_DEFINITIONS(-DZIP_STD)
|
ADD_DEFINITIONS(-DZIP_STD)
|
||||||
|
@ -3,10 +3,9 @@
|
|||||||
#include <osgDB/FileNameUtils>
|
#include <osgDB/FileNameUtils>
|
||||||
#include <osgDB/ReadFile>
|
#include <osgDB/ReadFile>
|
||||||
#include <osgDB/Registry>
|
#include <osgDB/Registry>
|
||||||
#include <osgDB/Options>
|
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "unzip.h"
|
#include "ZipArchive.h"
|
||||||
|
|
||||||
class ReaderWriterZIP : public osgDB::ReaderWriter
|
class ReaderWriterZIP : public osgDB::ReaderWriter
|
||||||
{
|
{
|
||||||
@ -15,251 +14,135 @@ class ReaderWriterZIP : public osgDB::ReaderWriter
|
|||||||
ReaderWriterZIP()
|
ReaderWriterZIP()
|
||||||
{
|
{
|
||||||
supportsExtension("zip","Zip archive format");
|
supportsExtension("zip","Zip archive format");
|
||||||
|
osgDB::Registry::instance()->addArchiveExtension("zip");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const char* className() const { return "ZIP Database Reader/Writer"; }
|
virtual const char* className() const { return "ZIP Database Reader/Writer"; }
|
||||||
|
|
||||||
virtual ReadResult readNode(const std::string& file, const osgDB::Options* options) const
|
|
||||||
{
|
|
||||||
ReadResult rresult = ReadResult::FILE_NOT_HANDLED;
|
|
||||||
|
|
||||||
//Check to see if option is to load and extract to filesystem
|
virtual ReadResult openArchive(const std::string& file,ArchiveStatus status, unsigned int indexBlockSize = 4096, const Options* options = NULL) const
|
||||||
bool bExtractToFileSystem = false;
|
|
||||||
if (options)
|
|
||||||
{
|
|
||||||
std::string optExtractTo = options->getPluginStringData("zipextract");
|
|
||||||
if (!(optExtractTo.empty()))
|
|
||||||
{
|
|
||||||
if (osgDB::convertToLowerCase(optExtractTo)=="filesystem")
|
|
||||||
{
|
|
||||||
bExtractToFileSystem = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bExtractToFileSystem)
|
|
||||||
{
|
|
||||||
rresult = original_readNode(file,options);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::string ext = osgDB::getLowerCaseFileExtension(file);
|
|
||||||
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
|
|
||||||
|
|
||||||
std::string fileName = osgDB::findDataFile( file, options );
|
|
||||||
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
|
|
||||||
|
|
||||||
OSG_INFO<<"ReaderWriterZIP::readNode( "<<fileName.c_str()<<" )\n";
|
|
||||||
|
|
||||||
// First open file as stream
|
|
||||||
osgDB::ifstream srcFileStrm(fileName.c_str(),std::ios::in|std::ios::binary);
|
|
||||||
if (!srcFileStrm.fail())
|
|
||||||
{
|
|
||||||
// Now read entire zip file into stream buffer
|
|
||||||
std::stringstream tmpStrmBuffer;
|
|
||||||
srcFileStrm.seekg(0,std::ios_base::beg);
|
|
||||||
tmpStrmBuffer.operator <<(srcFileStrm.rdbuf());
|
|
||||||
srcFileStrm.close();
|
|
||||||
|
|
||||||
// Setup appropriate options
|
|
||||||
osg::ref_ptr<Options> local_opt = options ?
|
|
||||||
static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) :
|
|
||||||
new Options;
|
|
||||||
|
|
||||||
// minor issue associated with database path list, as in context of zip file it
|
|
||||||
// doesn't make sense. Need to set to empty path for other plugins to access
|
|
||||||
local_opt->getDatabasePathList().push_front(osgDB::getFilePath(file));
|
|
||||||
|
|
||||||
// Now pass through to memory zip handler
|
|
||||||
rresult = readNode(tmpStrmBuffer,local_opt.get());
|
|
||||||
|
|
||||||
// Clean up options
|
|
||||||
local_opt->getDatabasePathList().pop_front();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rresult;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ReadResult readNode(std::istream& fin,const osgDB::Options* options) const
|
|
||||||
{
|
|
||||||
ReadResult result = ReadResult(ReadResult::FILE_NOT_HANDLED);
|
|
||||||
|
|
||||||
if (fin.fail()) return result;
|
|
||||||
|
|
||||||
fin.seekg(0,std::ios_base::end);
|
|
||||||
unsigned int ulzipFileLength = fin.tellg();
|
|
||||||
fin.seekg(0,std::ios_base::beg);
|
|
||||||
|
|
||||||
// Need to decouple stream content as I can't see any other way to get access to a byte array
|
|
||||||
// containing the content in the stream. One saving grace here is that we know that the
|
|
||||||
// stream has already been fully read in, hence no need to concern ourselves with asynchronous
|
|
||||||
// reads.
|
|
||||||
char * pMemBuffer = new char [ulzipFileLength];
|
|
||||||
if (!pMemBuffer) return result;
|
|
||||||
|
|
||||||
fin.read(pMemBuffer, ulzipFileLength);
|
|
||||||
if ((unsigned int)fin.gcount() == ulzipFileLength)
|
|
||||||
{
|
|
||||||
HZIP hz = OpenZip(pMemBuffer, ulzipFileLength, "");
|
|
||||||
if (hz)
|
|
||||||
{
|
|
||||||
ZIPENTRY ze;
|
|
||||||
GetZipItem(hz,-1,&ze);
|
|
||||||
int numitems=ze.index;
|
|
||||||
|
|
||||||
// Initialise top level group
|
|
||||||
osg::ref_ptr<osg::Group> grp = new osg::Group;
|
|
||||||
if (grp.valid())
|
|
||||||
{
|
|
||||||
// Now loop through each file in zip
|
|
||||||
for (int i = 0; i < numitems; i++)
|
|
||||||
{
|
|
||||||
GetZipItem(hz,i,&ze);
|
|
||||||
std::string StreamName = ze.name;
|
|
||||||
std::stringstream buffer;
|
|
||||||
|
|
||||||
char *ibuf = new char[ze.unc_size];
|
|
||||||
if (ibuf)
|
|
||||||
{
|
|
||||||
UnzipItem(hz,i, ibuf, ze.unc_size);
|
|
||||||
buffer.write(ibuf,ze.unc_size);
|
|
||||||
delete[] ibuf;
|
|
||||||
// Now ready to read node //
|
|
||||||
|
|
||||||
std::string file_ext = osgDB::getFileExtension(StreamName);
|
|
||||||
|
|
||||||
ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension(file_ext);
|
|
||||||
if (rw)
|
|
||||||
{
|
|
||||||
// Setup appropriate options
|
|
||||||
osg::ref_ptr<Options> local_opt = options ?
|
|
||||||
static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) :
|
|
||||||
new Options;
|
|
||||||
|
|
||||||
local_opt->setPluginStringData("STREAM_FILENAME",osgDB::getSimpleFileName(StreamName));
|
|
||||||
|
|
||||||
ReadResult readResult = rw->readNode(buffer,local_opt.get());
|
|
||||||
if (readResult.validNode())
|
|
||||||
{
|
|
||||||
grp->addChild(readResult.takeNode());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (grp->getNumChildren() > 0)
|
|
||||||
{
|
|
||||||
result = grp.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CloseZip(hz);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete [] pMemBuffer;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ReadResult original_readNode(const std::string& file, const osgDB::Options* options) const
|
|
||||||
{
|
{
|
||||||
|
|
||||||
std::string ext = osgDB::getLowerCaseFileExtension(file);
|
std::string ext = osgDB::getLowerCaseFileExtension(file);
|
||||||
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
|
if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
|
||||||
|
|
||||||
std::string fileName = osgDB::findDataFile( file, options );
|
std::string fileName = osgDB::findDataFile(file, options);
|
||||||
if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
|
if (fileName.empty())
|
||||||
|
|
||||||
OSG_INFO<<"ReaderWriterZIP::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_zip");
|
|
||||||
|
|
||||||
mkdir(dirname);
|
|
||||||
// Using unzip.exe from http://www.info-zip.org/pub/infozip/UnZip.html
|
|
||||||
// unzip.exe must be in your path. (PATH environment variable).
|
|
||||||
|
|
||||||
// OR - WinRAR
|
|
||||||
|
|
||||||
// Checking for WinRAR
|
|
||||||
std::string winrar = std::string( getenv( "ProgramFiles" ) ) + "/WinRAR/winrar.exe";
|
|
||||||
if ( osgDB::fileExists(winrar) ) {
|
|
||||||
sprintf( command,
|
|
||||||
"%s x -o+ \"%s\" \"%s\"", winrar.c_str(),
|
|
||||||
fileName.c_str(), dirname);
|
|
||||||
} else {
|
|
||||||
sprintf( command,
|
|
||||||
"unzip -o -qq \"%s\" -d \"%s\"",
|
|
||||||
fileName.c_str(), dirname);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
sprintf( dirname, "/tmp/.zip%06d", getpid());
|
|
||||||
mkdir( dirname, 0700 );
|
|
||||||
|
|
||||||
sprintf( command,
|
|
||||||
"unzip %s -d %s",
|
|
||||||
fileName.c_str(), dirname);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
OSG_INFO<<"Running command '"<<command<<"'"<<std::endl;
|
|
||||||
if ( system( command ) ) {
|
|
||||||
return ReadResult::FILE_NOT_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Group> grp = new osg::Group;
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// 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);
|
//we do not support writing so the file must exist
|
||||||
if (!acceptsExtension(file_ext) &&
|
return ReadResult::FILE_NOT_FOUND;
|
||||||
*itr!=std::string(".") &&
|
}
|
||||||
*itr!=std::string(".."))
|
|
||||||
|
// copy the incoming options if possible so that plugin options can be applied to files
|
||||||
|
// inside the archive
|
||||||
|
osg::ref_ptr<osgDB::ReaderWriter::Options> local_options = options?
|
||||||
|
options->cloneOptions() :
|
||||||
|
new osgDB::ReaderWriter::Options;
|
||||||
|
|
||||||
|
osg::ref_ptr<ZipArchive> archive = new ZipArchive;
|
||||||
|
if (!archive->open(fileName, osgDB::ReaderWriter::READ, local_options.get()))
|
||||||
{
|
{
|
||||||
osg::Node *node = osgDB::readNodeFile( *itr, local_options.get() );
|
return ReadResult(ReadResult::FILE_NOT_HANDLED);
|
||||||
grp->addChild( node );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
osgDB::Registry::instance()->setCreateNodeFromImage(prevCreateNodeFromImage);
|
return archive.get();
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
/** open an archive for reading.*/
|
||||||
// note, is this the right command for windows?
|
virtual ReadResult openArchive(std::istream& fin, const Options* options) const
|
||||||
// is there any way of overiding the Y/N option? RO.
|
|
||||||
sprintf( command, "erase /S /Q \"%s\"", dirname );
|
|
||||||
int result = system( command );
|
|
||||||
#else
|
|
||||||
|
|
||||||
sprintf( command, "rm -rf %s", dirname );
|
|
||||||
int result = system( command );
|
|
||||||
#endif
|
|
||||||
if (result!=0) return ReadResult::ERROR_IN_READING_FILE;
|
|
||||||
|
|
||||||
if( grp->getNumChildren() == 0 )
|
|
||||||
{
|
{
|
||||||
return ReadResult::FILE_NOT_HANDLED;
|
osg::ref_ptr<ZipArchive> archive = new ZipArchive;
|
||||||
|
if (!archive->open(fin, options))
|
||||||
|
{
|
||||||
|
return ReadResult(ReadResult::FILE_NOT_HANDLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return grp.get();
|
return archive.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const
|
||||||
|
{
|
||||||
|
osgDB::ReaderWriter::ReadResult result = openArchive(file, osgDB::Archive::READ);
|
||||||
|
|
||||||
|
if (!result.validArchive()) return result;
|
||||||
|
|
||||||
|
// copy the incoming options if possible so that plugin options can be applied to files
|
||||||
|
// inside the archive
|
||||||
|
osg::ref_ptr<osgDB::ReaderWriter::Options> local_options = options?
|
||||||
|
options->cloneOptions() :
|
||||||
|
new osgDB::ReaderWriter::Options;
|
||||||
|
|
||||||
|
local_options->setDatabasePath(file);
|
||||||
|
|
||||||
|
//todo- what should we read here?
|
||||||
|
osgDB::ReaderWriter::ReadResult result_2 = result.getArchive()->readNode(result.getArchive()->getMasterFileName(),local_options.get());
|
||||||
|
|
||||||
|
if (!options || (options->getObjectCacheHint() & osgDB::ReaderWriter::Options::CACHE_ARCHIVES))
|
||||||
|
{
|
||||||
|
// register the archive so that it is cached for future use.
|
||||||
|
osgDB::Registry::instance()->addToArchiveCache(file, result.getArchive());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result_2;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ReadResult readNode(std::istream& fin,const osgDB::ReaderWriter::Options* options) const
|
||||||
|
{
|
||||||
|
|
||||||
|
osgDB::ReaderWriter::ReadResult result = openArchive(fin, options);
|
||||||
|
|
||||||
|
if (!result.validArchive()) return result;
|
||||||
|
|
||||||
|
// copy the incoming options if possible so that plugin options can be applied to files
|
||||||
|
// inside the archive
|
||||||
|
osg::ref_ptr<osgDB::ReaderWriter::Options> local_options = options?
|
||||||
|
options->cloneOptions() :
|
||||||
|
new osgDB::ReaderWriter::Options;
|
||||||
|
|
||||||
|
//todo- what should the database path be?
|
||||||
|
//local_options->setDatabasePath(file);
|
||||||
|
|
||||||
|
|
||||||
|
//todo- what should we read here?
|
||||||
|
osgDB::ReaderWriter::ReadResult result_2 = result.getArchive()->readNode(result.getArchive()->getMasterFileName(),local_options.get());
|
||||||
|
|
||||||
|
//todo- what to do to cache the archive here?
|
||||||
|
//if (!options || (options->getObjectCacheHint() & osgDB::ReaderWriter::Options::CACHE_ARCHIVES))
|
||||||
|
//{
|
||||||
|
// // register the archive so that it is cached for future use.
|
||||||
|
// osgDB::Registry::instance()->addToArchiveCache(file, result.getArchive());
|
||||||
|
//}
|
||||||
|
|
||||||
|
return result_2;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ReadResult readImage(const std::string& file,const Options* options) const
|
||||||
|
{
|
||||||
|
ReadResult result = openArchive(file,osgDB::Archive::READ);
|
||||||
|
|
||||||
|
if (!result.validArchive()) return result;
|
||||||
|
|
||||||
|
|
||||||
|
// copy the incoming options if possible so that plugin options can be applied to files
|
||||||
|
// inside the archive
|
||||||
|
osg::ref_ptr<osgDB::ReaderWriter::Options> local_options = options?
|
||||||
|
options->cloneOptions() :
|
||||||
|
new osgDB::ReaderWriter::Options;
|
||||||
|
|
||||||
|
local_options->setDatabasePath(file);
|
||||||
|
|
||||||
|
ReadResult result_2 = result.getArchive()->readImage(result.getArchive()->getMasterFileName(),local_options.get());
|
||||||
|
|
||||||
|
|
||||||
|
if (!options || (options->getObjectCacheHint() & osgDB::ReaderWriter::Options::CACHE_ARCHIVES))
|
||||||
|
{
|
||||||
|
// register the archive so that it is cached for future use.
|
||||||
|
osgDB::Registry::instance()->addToArchiveCache(file, result.getArchive());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -4203,10 +4203,25 @@ ZRESULT TUnzip::Unzip(int index,void *dst,unsigned int len,DWORD flags)
|
|||||||
}
|
}
|
||||||
bool reached_eof;
|
bool reached_eof;
|
||||||
int res = unzReadCurrentFile(uf,dst,len,&reached_eof);
|
int res = unzReadCurrentFile(uf,dst,len,&reached_eof);
|
||||||
if (res<=0) {unzCloseCurrentFile(uf); currentfile=-1;}
|
if (res<=0)
|
||||||
if (reached_eof) return ZR_OK;
|
{
|
||||||
if (res>0) return ZR_MORE;
|
unzCloseCurrentFile(uf); currentfile=-1;
|
||||||
if (res==UNZ_PASSWORD) return ZR_PASSWORD;
|
}
|
||||||
|
if (reached_eof)
|
||||||
|
{
|
||||||
|
unzCloseCurrentFile(uf);
|
||||||
|
currentfile=-1;
|
||||||
|
return ZR_OK;
|
||||||
|
}
|
||||||
|
if (res>0)
|
||||||
|
{
|
||||||
|
return ZR_MORE;
|
||||||
|
}
|
||||||
|
if (res==UNZ_PASSWORD)
|
||||||
|
{
|
||||||
|
return ZR_PASSWORD;
|
||||||
|
}
|
||||||
|
|
||||||
return ZR_FLATE;
|
return ZR_FLATE;
|
||||||
}
|
}
|
||||||
// otherwise we're writing to a handle or a file
|
// otherwise we're writing to a handle or a file
|
||||||
|
Loading…
Reference in New Issue
Block a user