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