1 #include <osgDB/FileNameUtils>
2 #include <osgDB/FileUtils>
3 #include <osgDB/ReadFile>
4 #include <osgDB/Registry>
5 #include <osgDB/DatabaseRevisions>
6 #include <osg/Notify>
7 
8 class ReaderWriterRevisions : public osgDB::ReaderWriter
9 {
10     public:
ReaderWriterRevisions()11         ReaderWriterRevisions()
12         {
13             supportsExtension("revisions","list of revision files");
14             supportsExtension("added","revision file containing list of added files");
15             supportsExtension("removed","revision file containing list of removed files");
16             supportsExtension("modified","revision file containing list of modified files");
17         }
18 
className() const19         virtual const char* className() const { return "Revisions Font Reader/Writer"; }
20 
readObject(const std::string & file,const osgDB::ReaderWriter::Options * options) const21         virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options) const
22         {
23             std::string ext = osgDB::getLowerCaseFileExtension(file);
24             if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
25 
26             std::string fileName = osgDB::findDataFile( file, options );
27             if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
28 
29             osgDB::ifstream fin(fileName.c_str());
30 
31             if (ext=="revisions") return readRevisions(fin, file, options);
32             else return readFileList(fin, file, options);
33         }
34 
readObject(std::istream & fin,const osgDB::ReaderWriter::Options * options) const35         virtual ReadResult readObject(std::istream& fin, const osgDB::ReaderWriter::Options* options) const
36         {
37             std::string fileName = options->getPluginStringData("filename");
38             if (fileName.empty())
39             {
40                 OSG_NOTICE<<"Error: ReaderWriterRevision unable to determine stream type, cannot not read file."<<std::endl;
41                 return ReadResult::FILE_NOT_HANDLED;
42             }
43 
44             std::string ext = osgDB::getLowerCaseFileExtension(fileName);
45             if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
46 
47             if (ext=="revisions") return readRevisions(fin, fileName, options);
48             else return readFileList(fin, fileName, options);
49         }
50 
readFileList(std::istream & fin,const std::string & name,const osgDB::ReaderWriter::Options *) const51         ReadResult readFileList(std::istream& fin, const std::string& name, const osgDB::ReaderWriter::Options* /*options*/) const
52         {
53             OSG_INFO<<"    readFileList="<<name<<std::endl;
54 
55             osg::ref_ptr<osgDB::FileList> fileList = new osgDB::FileList;
56             fileList->setName(name);
57 
58             while(fin)
59             {
60                 std::string filename;
61                 fin >> filename;
62                 OSG_INFO<<"        ="<<filename<<std::endl;
63 
64                 if (!filename.empty()) fileList->getFileNames().insert(filename);
65             }
66 
67             return fileList.get();
68         }
69 
readRevisions(std::istream & fin,const std::string & name,const osgDB::ReaderWriter::Options * options) const70         ReadResult readRevisions(std::istream& fin, const std::string& name, const osgDB::ReaderWriter::Options* options) const
71         {
72             osg::ref_ptr<osgDB::DatabaseRevisions> revisions = new osgDB::DatabaseRevisions;
73             revisions->setName(name);
74 
75             typedef std::map<std::string, osg::ref_ptr<osgDB::DatabaseRevision> > RevisionMap;
76             RevisionMap revisionMap;
77 
78             std::string revisions_path;
79             if (options && !(options->getDatabasePathList().empty())) revisions_path = options->getDatabasePathList().front();
80             else revisions_path = osgDB::getFilePath(name);
81 
82             revisions->setDatabasePath(revisions_path);
83 
84             OSG_INFO<<"readRevisions="<<name<<std::endl;
85             OSG_INFO<<"  revisions_path="<<revisions_path<<std::endl;
86 
87             bool loadFileLists = false;
88 
89             while(fin)
90             {
91                 std::string filename;
92                 fin >> filename;
93 
94                 OSG_INFO<<"    filename="<<filename<<std::endl;
95 
96                 if (!filename.empty())
97                 {
98                     std::string ext = osgDB::getLowerCaseFileExtension(filename);
99                     std::string revisionName = osgDB::getNameLessExtension(filename);
100                     if (!revisionName.empty())
101                     {
102                         osg::ref_ptr<osgDB::DatabaseRevision>& dbRevision = revisionMap[revisionName];
103                         if (!dbRevision)
104                         {
105                             dbRevision = new osgDB::DatabaseRevision;
106                             dbRevision->setName(revisionName);
107                             dbRevision->setDatabasePath(revisions_path);
108                         }
109 
110                         osg::ref_ptr<osgDB::FileList> fileList;
111 
112 
113                         if (loadFileLists)
114                         {
115                             std::string complete_path = osgDB::concatPaths(revisions_path, filename);
116                             OSG_INFO<<"    complete_path="<<complete_path<<std::endl;
117                             fileList = osgDB::readRefFile<osgDB::FileList>(complete_path, options);
118                         }
119 
120                         if (!fileList)
121                         {
122                             fileList = new osgDB::FileList;
123                             fileList->setName(filename);
124                         }
125 
126                         if (ext=="added")
127                         {
128                             dbRevision->setFilesAdded(fileList.get());
129                         }
130                         else if (ext=="removed")
131                         {
132                             dbRevision->setFilesRemoved(fileList.get());
133                         }
134                         else if (ext=="modified")
135                         {
136                             dbRevision->setFilesModified(fileList.get());
137                         }
138                     }
139                 }
140             }
141 
142             for(RevisionMap::iterator itr = revisionMap.begin();
143                 itr != revisionMap.end();
144                 ++itr)
145             {
146                 revisions->addRevision(itr->second.get());
147             }
148 
149             return revisions.get();
150         }
151 
writeObject(const osg::Object & object,std::ostream & fout,const osgDB::ReaderWriter::Options *) const152         virtual WriteResult writeObject(const osg::Object& object, std::ostream& fout,const osgDB::ReaderWriter::Options*) const
153         {
154             const osgDB::FileList* fileList = dynamic_cast<const osgDB::FileList*>(&object);
155             if (fileList)
156             {
157                 const osgDB::FileList::FileNames& fileNames = fileList->getFileNames();
158                 for(osgDB::FileList::FileNames::const_iterator itr = fileNames.begin();
159                     itr != fileNames.end();
160                     ++itr)
161                 {
162                     fout<<*itr<<std::endl;
163                 }
164                 return WriteResult::FILE_SAVED;
165             }
166 
167             const osgDB::DatabaseRevisions* revisions = dynamic_cast<const osgDB::DatabaseRevisions*>(&object);
168             if (revisions)
169             {
170                 typedef osgDB::DatabaseRevisions::DatabaseRevisionList RevisionList;
171                 const RevisionList& revisionList  = revisions->getDatabaseRevisionList();
172                 for(RevisionList::const_iterator itr = revisionList.begin();
173                     itr != revisionList.end();
174                     ++itr)
175                 {
176                     const osgDB::DatabaseRevision* revision = itr->get();
177                     if (revision->getFilesAdded())
178                     {
179                         if (!(revision->getFilesAdded()->getName().empty())) fout<<revision->getFilesAdded()->getName()<<std::endl;
180                         else fout<<"FilesAdded entry had no name assigned."<<std::endl;
181                     }
182 
183                     if (revision->getFilesRemoved())
184                     {
185                         if (!(revision->getFilesRemoved()->getName().empty())) fout<<revision->getFilesRemoved()->getName()<<std::endl;
186                         else fout<<"FilesAdded entry had no name assigned."<<std::endl;
187                     }
188 
189                     if (revision->getFilesModified())
190                     {
191                         if (!(revision->getFilesModified()->getName().empty())) fout<<revision->getFilesModified()->getName()<<std::endl;
192                         else fout<<"FilesAdded entry had no name assigned."<<std::endl;
193                     }
194                 }
195             }
196 
197             return WriteResult::FILE_NOT_HANDLED;
198         }
199 
writeObject(const osg::Object & object,const std::string & fileName,const osgDB::ReaderWriter::Options * options) const200         virtual WriteResult writeObject(const osg::Object& object,const std::string& fileName, const osgDB::ReaderWriter::Options* options) const
201         {
202             std::string ext = osgDB::getFileExtension(fileName);
203             if (!acceptsExtension(ext)) return WriteResult::FILE_NOT_HANDLED;
204 
205             osgDB::ofstream fout(fileName.c_str());
206             if(!fout) return WriteResult::ERROR_IN_WRITING_FILE;
207 
208             return writeObject(object, fout, options);
209         }
210 };
211 
212 // now register with Registry to instantiate the above
213 // reader/writer.
214 REGISTER_OSGPLUGIN(revisions, ReaderWriterRevisions)
215