root/OpenSceneGraph/trunk/src/osgPlugins/zip/ReaderWriterZIP.cpp @ 13041

Revision 13041, 8.4 kB (checked in by robert, 3 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osg/Group>
2#include <osgDB/FileUtils>
3#include <osgDB/FileNameUtils>
4#include <osgDB/ReadFile>
5#include <osgDB/Registry>
6
7#include <sstream>
8#include "ZipArchive.h"
9
10class ReaderWriterZIP : public osgDB::ReaderWriter
11{
12    public:
13
14        ReaderWriterZIP()
15        {
16            supportsExtension("zip","Zip archive format");
17            osgDB::Registry::instance()->addArchiveExtension("zip");
18        }
19
20        virtual const char* className() const { return "ZIP Database Reader/Writer"; }
21
22
23        virtual ReadResult openArchive(const std::string& file,ArchiveStatus status, unsigned int indexBlockSize = 4096, const Options* options = NULL) const
24        {
25
26            std::string ext = osgDB::getLowerCaseFileExtension(file);
27            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
28
29            std::string fileName = osgDB::findDataFile(file, options);
30            if (fileName.empty())
31            {
32                //we do not support writing so the file must exist
33                return ReadResult::FILE_NOT_FOUND;
34            }
35
36            // copy the incoming options if possible so that plugin options can be applied to files
37            // inside the archive
38            osg::ref_ptr<osgDB::ReaderWriter::Options> local_options =  options?
39                options->cloneOptions() :
40                new osgDB::ReaderWriter::Options;
41
42            osg::ref_ptr<ZipArchive> archive = new ZipArchive;
43            if (!archive->open(fileName, osgDB::ReaderWriter::READ, local_options.get()))
44            {
45                return ReadResult(ReadResult::FILE_NOT_HANDLED);
46            }
47
48            return archive.get();
49        }
50
51        /** open an archive for reading.*/
52        virtual ReadResult openArchive(std::istream& fin, const Options* options) const
53        {
54            osg::ref_ptr<ZipArchive> archive = new ZipArchive;
55            if (!archive->open(fin, options))
56            {
57                return ReadResult(ReadResult::FILE_NOT_HANDLED);
58            }
59
60            return archive.get();
61        }
62
63        osgDB::ReaderWriter::ReadResult readNodeFromArchive(osgDB::Archive& archive, const osgDB::ReaderWriter::Options* options) const
64        {
65            osgDB::ReaderWriter::ReadResult result(osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND);
66
67            if (!archive.getMasterFileName().empty())
68            {
69                result = archive.readNode(archive.getMasterFileName(), options);
70            }
71            else
72            {
73                osgDB::Archive::FileNameList fileNameList;
74                if (archive.getFileNames(fileNameList))
75                {
76                    typedef std::list< osg::ref_ptr<osg::Node> > Nodes;
77                    Nodes nodes;
78                    for(osgDB::Archive::FileNameList::iterator itr = fileNameList.begin();
79                        itr != fileNameList.end();
80                        ++itr)
81                    {
82                        result = archive.readNode(*itr, options);
83                        if (result.validNode()) nodes.push_back(result.getNode());
84                    }
85
86                    if (!nodes.empty())
87                    {
88                        if (nodes.size()==1)
89                        {
90                            result = osgDB::ReaderWriter::ReadResult(nodes.front().get());
91                        }
92                        else
93                        {
94                            osg::ref_ptr<osg::Group> group = new osg::Group;
95                            for(Nodes::iterator itr = nodes.begin();
96                                itr != nodes.end();
97                                ++itr)
98                            {
99                                group->addChild(itr->get());
100                            }
101                            result = osgDB::ReaderWriter::ReadResult(group.get());
102                        }
103                    }
104                }
105            }
106            return result;
107        }
108
109
110        virtual osgDB::ReaderWriter::ReadResult readNode(const std::string& file, const osgDB::ReaderWriter::Options* options) const
111        {
112            osgDB::ReaderWriter::ReadResult result = openArchive(file, osgDB::Archive::READ);
113
114            if (!result.validArchive()) return result;
115
116            osg::ref_ptr<osgDB::Archive> archive = result.getArchive();
117
118            if (!options || (options->getObjectCacheHint() & osgDB::ReaderWriter::Options::CACHE_ARCHIVES))
119            {
120                // register the archive so that it is cached for future use.
121                osgDB::Registry::instance()->addToArchiveCache(file, archive.get());
122            }
123
124            // copy the incoming options if possible so that plugin options can be applied to files
125            // inside the archive
126            osg::ref_ptr<osgDB::ReaderWriter::Options> local_options = options?
127                options->cloneOptions() :
128                new osgDB::ReaderWriter::Options;
129
130            local_options->setDatabasePath(file);
131
132            return readNodeFromArchive(*archive, local_options.get());
133        }
134
135        virtual ReadResult readNode(std::istream& fin,const osgDB::ReaderWriter::Options* options) const
136        {
137            osgDB::ReaderWriter::ReadResult result = openArchive(fin, options);
138
139            if (!result.validArchive()) return result;
140
141            osg::ref_ptr<osgDB::Archive> archive = result.getArchive();
142
143            // copy the incoming options if possible so that plugin options can be applied to files
144            // inside the archive
145            osg::ref_ptr<osgDB::ReaderWriter::Options> local_options = options?
146                options->cloneOptions() :
147                new osgDB::ReaderWriter::Options;
148
149            return readNodeFromArchive(*archive, local_options.get());
150        }
151
152        osgDB::ReaderWriter::ReadResult readImageFromArchive(osgDB::Archive& archive, const osgDB::ReaderWriter::Options* options) const
153        {
154            osgDB::ReaderWriter::ReadResult result(osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND);
155
156            if (!archive.getMasterFileName().empty())
157            {
158                result = archive.readImage(archive.getMasterFileName(), options);
159            }
160            else
161            {
162                osgDB::Archive::FileNameList fileNameList;
163                if (archive.getFileNames(fileNameList))
164                {
165                    for(osgDB::Archive::FileNameList::iterator itr = fileNameList.begin();
166                        itr != fileNameList.end() && !result.validImage();
167                        ++itr)
168                    {
169                        result = archive.readImage(*itr, options);
170                    }
171                }
172            }
173            return result;
174        }
175
176        virtual ReadResult readImage(const std::string& file,const Options* options) const
177        {
178            osgDB::ReaderWriter::ReadResult result = openArchive(file, osgDB::Archive::READ);
179
180            if (!result.validArchive()) return result;
181
182            osg::ref_ptr<osgDB::Archive> archive = result.getArchive();
183
184            if (!options || (options->getObjectCacheHint() & osgDB::ReaderWriter::Options::CACHE_ARCHIVES))
185            {
186                // register the archive so that it is cached for future use.
187                osgDB::Registry::instance()->addToArchiveCache(file, archive.get());
188            }
189
190            // copy the incoming options if possible so that plugin options can be applied to files
191            // inside the archive
192            osg::ref_ptr<osgDB::ReaderWriter::Options> local_options = options?
193                options->cloneOptions() :
194                new osgDB::ReaderWriter::Options;
195
196            local_options->setDatabasePath(file);
197
198            return readImageFromArchive(*archive, local_options.get());
199        }
200
201        virtual ReadResult readImage(std::istream& fin,const osgDB::ReaderWriter::Options* options) const
202        {
203            osgDB::ReaderWriter::ReadResult result = openArchive(fin, options);
204
205            if (!result.validArchive()) return result;
206
207            osg::ref_ptr<osgDB::Archive> archive = result.getArchive();
208
209            // copy the incoming options if possible so that plugin options can be applied to files
210            // inside the archive
211            osg::ref_ptr<osgDB::ReaderWriter::Options> local_options = options?
212                options->cloneOptions() :
213                new osgDB::ReaderWriter::Options;
214
215            return readImageFromArchive(*archive, local_options.get());
216        }
217};
218
219// now register with sgRegistry to instantiate the above
220// reader/writer.
221REGISTER_OSGPLUGIN(zip, ReaderWriterZIP)
Note: See TracBrowser for help on using the browser.