osgEarth 2.1.1
Public Types | Public Member Functions

ReaderWriterZipFS Class Reference

List of all members.

Public Types

enum  ObjectType { OBJECT, IMAGE, HEIGHTFIELD, NODE }

Public Member Functions

 ReaderWriterZipFS ()
virtual const char * className ()
virtual ReadResult readNode (const std::string &file_name, const Options *options) const
virtual ReadResult readImage (const std::string &file_name, const Options *options) const
virtual ReadResult readObject (const std::string &file_name, const Options *options) const
virtual ReadResult readHeightField (const std::string &file_name, const Options *options) const
virtual WriteResult writeObject (const osg::Object &obj, const std::string &fileName, const osgDB::ReaderWriter::Options *options) const
virtual WriteResult writeImage (const osg::Image &image, const std::string &fileName, const osgDB::ReaderWriter::Options *options) const
virtual WriteResult writeHeightField (const osg::HeightField &hf, const std::string &fileName, const osgDB::ReaderWriter::Options *options) const
virtual WriteResult writeNode (const osg::Node &node, const std::string &fileName, const osgDB::ReaderWriter::Options *options) const
WriteResult writeFile (ObjectType objectType, const osg::Object *object, osgDB::ReaderWriter *rw, std::ostream &fout, const osgDB::ReaderWriter::Options *options) const
ReadResult readFile (ObjectType objectType, osgDB::ReaderWriter *rw, std::istream &fin, const osgDB::ReaderWriter::Options *options) const
ReadResult readFile (ObjectType objectType, const std::string &fullFileName, const osgDB::ReaderWriter::Options *options) const
WriteResult writeFile (ObjectType objectType, const osg::Object *object, const std::string &fullFileName, const osgDB::ReaderWriter::Options *options) const

Detailed Description

The ZipFS plugin allows you to treat zip files almost like a virtual file system. You can read and write objects from zips using paths like c:/data/models.zip/cow.osg where cow.osg is a file within the models.zip file.

Definition at line 43 of file ReaderWriterZipFS.cpp.


Member Enumeration Documentation

Enumerator:
OBJECT 
IMAGE 
HEIGHTFIELD 
NODE 

Definition at line 47 of file ReaderWriterZipFS.cpp.


Constructor & Destructor Documentation

ReaderWriterZipFS::ReaderWriterZipFS ( ) [inline]

Definition at line 55 of file ReaderWriterZipFS.cpp.

    {
        supportsExtension( "zipfs", "Zip virtual file system" );
    }

Member Function Documentation

virtual const char* ReaderWriterZipFS::className ( ) [inline, virtual]

Definition at line 60 of file ReaderWriterZipFS.cpp.

    {
        return "ZIP virtual file system";
    }
ReadResult ReaderWriterZipFS::readFile ( ObjectType  objectType,
osgDB::ReaderWriter *  rw,
std::istream &  fin,
const osgDB::ReaderWriter::Options *  options 
) const [inline]

Definition at line 119 of file ReaderWriterZipFS.cpp.

    {
        switch (objectType)
        {
          case(OBJECT): return rw->readObject(fin, options);
          case(IMAGE): return rw->readImage(fin, options);
          case(HEIGHTFIELD): return rw->readHeightField(fin, options);
          case(NODE): return rw->readNode(fin, options);
          default: break;
        }
        return ReadResult::FILE_NOT_HANDLED;
    }
ReadResult ReaderWriterZipFS::readFile ( ObjectType  objectType,
const std::string &  fullFileName,
const osgDB::ReaderWriter::Options *  options 
) const [inline]

Definition at line 132 of file ReaderWriterZipFS.cpp.

    {
        OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(s_mutex);

        //This plugin allows you to treat zip files almost like virtual directories.  So, the pathname to the file you want in the zip should
        //be of the format c:\data\myzip.zip\images\foo.png

        std::string::size_type len = fullFileName.find(".zip");
        if (len == std::string::npos)
        {
            osg::notify(osg::INFO) << "ReaderWriterZipFS: Path does not contain zip file" << std::endl;
            return ReadResult::FILE_NOT_HANDLED;
        }

        std::string zipFile = fullFileName.substr(0, len + 4);
        zipFile = osgDB::findDataFile(zipFile);
        zipFile = osgDB::convertFileNameToNativeStyle( zipFile );

        //Return if the file doesn't exist
        if (!osgDB::fileExists( zipFile )) return ReadResult::FILE_NOT_FOUND;

        osg::notify(osg::INFO) << "ReaderWriterZipFS::readFile  ZipFile path is " << zipFile << std::endl;

        std::string zipEntry = fullFileName.substr(len+4);


        //Strip the leading slash from the zip entry
        if ((zipEntry.length() > 0) && 
            ((zipEntry[0] == '/') || (zipEntry[0] == '\\')))
        {
            zipEntry = zipEntry.substr(1);
        }


        //Lipzip returns filenames with '/' rather than '\\', even on Windows.  So, convert the zip entry to Unix style
        zipEntry = osgDB::convertFileNameToUnixStyle(zipEntry);
        osg::notify(osg::INFO) << "Zip Entry " << zipEntry << std::endl;

        //See if we can get a ReaderWriter for the zip entry before we even try to unzip the file
         ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension(osgDB::getFileExtension(zipEntry));
         if (!rw)
         {
             osg::notify(osg::NOTICE) << "Could not find ReaderWriter for " << zipEntry << std::endl;
             return ReadResult::FILE_NOT_HANDLED;
         }


        int err;

        //Open the zip file
        struct zip* pZip = zip_open(zipFile.c_str(), ZIP_CHECKCONS, &err);
        if (pZip)
        {
            //List the files
            /*int numFiles = zip_get_num_files(pZip);
            osg::notify(osg::NOTICE) << zipFile << " has " << numFiles << " files " << std::endl;
            for (int i = 0; i < numFiles; ++i)
            {
            osg::notify(osg::NOTICE) << i << ": " << zip_get_name(pZip, i, 0) << std::endl;
            }*/

            //Find the index within the zip file for the given zip entry
            int zipIndex = zip_name_locate(pZip, zipEntry.c_str(), 0);

            osg::notify(osg::INFO) << "ReaderWriterZipFS: ZipFile index " << zipIndex << std::endl;
            if (zipIndex < 0)
            {
                osg::notify(osg::INFO) << "Could not find zip entry " << zipEntry << " in " << zipFile << std::endl;
                //Make sure to close the zipfile
                zip_close(pZip);
                return ReadResult::FILE_NOT_FOUND;  
            }
            
            //Open the entry for reading
            zip_file* pZipFile = zip_fopen_index(pZip, zipIndex, 0);

            if (pZipFile) 
            {
                //Read the data from the entry into a std::string
                int dataSize = 0;
                std::string data;
                do{
                    char buffer[1024];
                    dataSize = zip_fread(pZipFile, buffer, 1024);
                    if (dataSize > 0)
                    {
                       data.append((char*)buffer, dataSize);
                    }
                }while (dataSize > 0);

                //Close the zip entry and the actual zip file itself
                zip_fclose(pZipFile);
                zip_close(pZip);

                std::stringstream strstream(data);
                return readFile(objectType, rw, strstream, options);
            }
        }
        else
        {
            osg::notify(osg::NOTICE) << "ReaderWriterZipFS::readFile couldn't open zip " << zipFile << " full filename " << fullFileName << std::endl;
        }
        return ReadResult::FILE_NOT_HANDLED;
    }

Here is the call graph for this function:

virtual ReadResult ReaderWriterZipFS::readHeightField ( const std::string &  file_name,
const Options options 
) const [inline, virtual]

Definition at line 80 of file ReaderWriterZipFS.cpp.

    {
        return readFile(HEIGHTFIELD, file_name, options);
    }
virtual ReadResult ReaderWriterZipFS::readImage ( const std::string &  file_name,
const Options options 
) const [inline, virtual]

Definition at line 70 of file ReaderWriterZipFS.cpp.

    {
        return readFile(IMAGE, file_name, options);
    }
virtual ReadResult ReaderWriterZipFS::readNode ( const std::string &  file_name,
const Options options 
) const [inline, virtual]

Definition at line 65 of file ReaderWriterZipFS.cpp.

    {
        return readFile(NODE, file_name, options);
    }
virtual ReadResult ReaderWriterZipFS::readObject ( const std::string &  file_name,
const Options options 
) const [inline, virtual]

Definition at line 75 of file ReaderWriterZipFS.cpp.

    {
        return readFile(OBJECT, file_name, options);
    }
WriteResult ReaderWriterZipFS::writeFile ( ObjectType  objectType,
const osg::Object *  object,
const std::string &  fullFileName,
const osgDB::ReaderWriter::Options *  options 
) const [inline]

Definition at line 237 of file ReaderWriterZipFS.cpp.

    {       
        OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(s_mutex);

        std::string::size_type len = fullFileName.find(".zip");
        if (len == std::string::npos)
        {
            osg::notify(osg::INFO) << "ReaderWriterZipFS: Path does not contain zip file" << std::endl;
            return WriteResult::FILE_NOT_HANDLED;
        }

        //It is possible that the zip file doesn't currently exist, so we just use getRealPath instead of findDataFile as in the readFile method
        std::string zipFile = osgDB::getRealPath(fullFileName.substr(0, len + 4));

        std::string path = osgDB::getFilePath(zipFile);
        //If the path doesn't currently exist, create it
        if (!osgDB::fileExists(path) && !osgDB::makeDirectory(path))
        {
            osg::notify(osg::WARN) << "Couldn't create path " << path << std::endl;
        }

        osg::notify(osg::INFO) << "ReaderWriterZipFS::writeFile ZipFile path is " << zipFile << std::endl;

        std::string zipEntry = fullFileName.substr(len+4);


        //Strip the leading slash from the zip entry
        if ((zipEntry.length() > 0) && 
            ((zipEntry[0] == '/') || (zipEntry[0] == '\\')))
        {
            zipEntry = zipEntry.substr(1);
        }


        //Lipzip returns filenames with '/' rather than '\\', even on Windows.  So, convert the zip entry to Unix style
        zipEntry = osgDB::convertFileNameToUnixStyle(zipEntry);
        osg::notify(osg::INFO) << "Zip Entry " << zipEntry << std::endl;

        //See if we can get a ReaderWriter for the zip entry before we even try to unzip the file
         ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension(osgDB::getFileExtension(zipEntry));
         if (!rw)
         {
             osg::notify(osg::INFO) << "Could not find ReaderWriter for " << zipEntry << std::endl;
             return WriteResult::FILE_NOT_HANDLED;
         }

        int err;

        //Open the zip file
        struct zip* pZip = zip_open(zipFile.c_str(), ZIP_CREATE|ZIP_CHECKCONS, &err);
        if (pZip)
        {
            //Write the data to the stream
            std::ostringstream strstream;
            writeFile(objectType, object, rw, strstream, options);

            char *data = new char[strstream.str().length()];
            memcpy(data, strstream.str().c_str(), strstream.str().size());

            WriteResult wr;
            struct zip_source *zs = zip_source_buffer(pZip, data, strstream.str().length(), 0);
            if (zs)
            {
                if (zip_add(pZip, zipEntry.c_str(), zs) != -1) 
                {
                    wr = WriteResult::FILE_SAVED;
                }
                else
                {
                  osg::notify(osg::NOTICE) << "Couldn't add zip source " << std::endl;
                  wr = WriteResult::ERROR_IN_WRITING_FILE;
                }
            }
            else
            {
                osg::notify(osg::NOTICE) << "Couldn't create zip source " << std::endl;
                wr = WriteResult::ERROR_IN_WRITING_FILE;
            }
            zip_close(pZip);
            delete[] data;
            return wr;
        }
        else
        {
            osg::notify(osg::NOTICE) << "ReaderWriterZipFS::writeFile couldn't open zip " << zipFile << " full filename " << fullFileName << std::endl;
        }
        return WriteResult::FILE_NOT_HANDLED;      
    }

Here is the call graph for this function:

WriteResult ReaderWriterZipFS::writeFile ( ObjectType  objectType,
const osg::Object *  object,
osgDB::ReaderWriter *  rw,
std::ostream &  fout,
const osgDB::ReaderWriter::Options *  options 
) const [inline]

Definition at line 105 of file ReaderWriterZipFS.cpp.

    {
        switch (objectType)
        {
        case(OBJECT): return rw->writeObject(*object, fout, options);
        case(IMAGE): return rw->writeImage(*(dynamic_cast<const osg::Image*>(object)), fout, options);
        case(HEIGHTFIELD): return rw->writeHeightField(*(dynamic_cast<const osg::HeightField*>(object)), fout, options);
        case(NODE): return rw->writeNode(*(dynamic_cast<const osg::Node*>(object)), fout,options);
        default: break;
        }
        return WriteResult::FILE_NOT_HANDLED;
    }
virtual WriteResult ReaderWriterZipFS::writeHeightField ( const osg::HeightField &  hf,
const std::string &  fileName,
const osgDB::ReaderWriter::Options *  options 
) const [inline, virtual]

Definition at line 95 of file ReaderWriterZipFS.cpp.

    {
        return writeFile(HEIGHTFIELD, &hf, fileName, options);
    }
virtual WriteResult ReaderWriterZipFS::writeImage ( const osg::Image &  image,
const std::string &  fileName,
const osgDB::ReaderWriter::Options *  options 
) const [inline, virtual]

Definition at line 90 of file ReaderWriterZipFS.cpp.

    {
        return writeFile(IMAGE, &image, fileName, options);
    }
virtual WriteResult ReaderWriterZipFS::writeNode ( const osg::Node &  node,
const std::string &  fileName,
const osgDB::ReaderWriter::Options *  options 
) const [inline, virtual]

Definition at line 100 of file ReaderWriterZipFS.cpp.

    {
        return writeFile(NODE, &node, fileName,options);
    }
virtual WriteResult ReaderWriterZipFS::writeObject ( const osg::Object &  obj,
const std::string &  fileName,
const osgDB::ReaderWriter::Options *  options 
) const [inline, virtual]

Definition at line 85 of file ReaderWriterZipFS.cpp.

    {
        return writeFile(OBJECT, &obj, fileName, options);
    }

The documentation for this class was generated from the following file:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines