| 1 | /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield |
|---|
| 2 | * |
|---|
| 3 | * This library is open source and may be redistributed and/or modified under |
|---|
| 4 | * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or |
|---|
| 5 | * (at your option) any later version. The full license is in LICENSE file |
|---|
| 6 | * included with this distribution, and on the openscenegraph.org website. |
|---|
| 7 | * |
|---|
| 8 | * This library is distributed in the hope that it will be useful, |
|---|
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 11 | * OpenSceneGraph Public License for more details. |
|---|
| 12 | */ |
|---|
| 13 | |
|---|
| 14 | #ifndef OSGDB_READERWRITER |
|---|
| 15 | #define OSGDB_READERWRITER 1 |
|---|
| 16 | |
|---|
| 17 | #include <osg/Image> |
|---|
| 18 | #include <osg/Shape> |
|---|
| 19 | #include <osg/Node> |
|---|
| 20 | |
|---|
| 21 | #include <osgDB/AuthenticationMap> |
|---|
| 22 | |
|---|
| 23 | #include <deque> |
|---|
| 24 | #include <list> |
|---|
| 25 | #include <iosfwd> |
|---|
| 26 | |
|---|
| 27 | namespace osgDB { |
|---|
| 28 | |
|---|
| 29 | class Archive; |
|---|
| 30 | |
|---|
| 31 | /** List of directories to search through which searching for files. */ |
|---|
| 32 | typedef std::deque<std::string> FilePathList; |
|---|
| 33 | |
|---|
| 34 | // forward declare |
|---|
| 35 | class Options; |
|---|
| 36 | |
|---|
| 37 | /** Pure virtual base class for reading and writing of non native formats. */ |
|---|
| 38 | class OSGDB_EXPORT ReaderWriter : public osg::Object |
|---|
| 39 | { |
|---|
| 40 | public: |
|---|
| 41 | |
|---|
| 42 | |
|---|
| 43 | ReaderWriter(): |
|---|
| 44 | osg::Object(true) {} |
|---|
| 45 | |
|---|
| 46 | ReaderWriter(const ReaderWriter& rw,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY): |
|---|
| 47 | osg::Object(rw,copyop) {} |
|---|
| 48 | |
|---|
| 49 | virtual ~ReaderWriter(); |
|---|
| 50 | |
|---|
| 51 | META_Object(osgDB,ReaderWriter); |
|---|
| 52 | |
|---|
| 53 | typedef std::map<std::string, std::string> FormatDescriptionMap; |
|---|
| 54 | typedef std::list<std::string> FeatureList; |
|---|
| 55 | |
|---|
| 56 | /** Return which protocols are supported by ReaderWriter. */ |
|---|
| 57 | virtual const FormatDescriptionMap& supportedProtocols() const { return _supportedProtocols; } |
|---|
| 58 | |
|---|
| 59 | /** Return which list of file extensions supported by ReaderWriter. */ |
|---|
| 60 | virtual const FormatDescriptionMap& supportedExtensions() const { return _supportedExtensions; } |
|---|
| 61 | |
|---|
| 62 | /** Return which list of file extensions supported by ReaderWriter. */ |
|---|
| 63 | virtual const FormatDescriptionMap& supportedOptions() const { return _supportedOptions; } |
|---|
| 64 | |
|---|
| 65 | /** Return true if ReaderWriter accepts specified file extension.*/ |
|---|
| 66 | virtual bool acceptsExtension(const std::string& /*extension*/) const; |
|---|
| 67 | |
|---|
| 68 | /// Bit mask for setting up which feature types are available for read and/or write |
|---|
| 69 | enum Features |
|---|
| 70 | { |
|---|
| 71 | FEATURE_NONE = 0, |
|---|
| 72 | FEATURE_READ_OBJECT = 1<<0, |
|---|
| 73 | FEATURE_READ_IMAGE = 1<<1, |
|---|
| 74 | FEATURE_READ_HEIGHT_FIELD = 1<<2, |
|---|
| 75 | FEATURE_READ_NODE = 1<<3, |
|---|
| 76 | FEATURE_READ_SHADER = 1<<4, |
|---|
| 77 | FEATURE_WRITE_OBJECT = 1<<5, |
|---|
| 78 | FEATURE_WRITE_IMAGE = 1<<6, |
|---|
| 79 | FEATURE_WRITE_HEIGHT_FIELD = 1<<7, |
|---|
| 80 | FEATURE_WRITE_NODE = 1<<8, |
|---|
| 81 | FEATURE_WRITE_SHADER = 1<<9, |
|---|
| 82 | FEATURE_ALL = FEATURE_READ_OBJECT | |
|---|
| 83 | FEATURE_READ_IMAGE | |
|---|
| 84 | FEATURE_READ_HEIGHT_FIELD | |
|---|
| 85 | FEATURE_READ_NODE | |
|---|
| 86 | FEATURE_READ_SHADER | |
|---|
| 87 | FEATURE_WRITE_OBJECT | |
|---|
| 88 | FEATURE_WRITE_IMAGE | |
|---|
| 89 | FEATURE_WRITE_HEIGHT_FIELD | |
|---|
| 90 | FEATURE_WRITE_NODE | |
|---|
| 91 | FEATURE_WRITE_SHADER |
|---|
| 92 | }; |
|---|
| 93 | /** Return available features*/ |
|---|
| 94 | virtual Features supportedFeatures() const; |
|---|
| 95 | |
|---|
| 96 | /** Return feature as string */ |
|---|
| 97 | static FeatureList featureAsString(Features feature); |
|---|
| 98 | |
|---|
| 99 | |
|---|
| 100 | |
|---|
| 101 | class OSGDB_EXPORT ReadResult |
|---|
| 102 | { |
|---|
| 103 | public: |
|---|
| 104 | |
|---|
| 105 | enum ReadStatus |
|---|
| 106 | { |
|---|
| 107 | NOT_IMPLEMENTED, //!< read*() method not implemented in concrete ReaderWriter. |
|---|
| 108 | FILE_NOT_HANDLED, //!< File is not appropriate for this file reader, due to some incompatibility, but *not* a read error. |
|---|
| 109 | FILE_NOT_FOUND, //!< File could not be found or could not be read. |
|---|
| 110 | FILE_LOADED, //!< File successfully found, loaded, and converted into osg. |
|---|
| 111 | FILE_LOADED_FROM_CACHE, //!< File found in cache and returned. |
|---|
| 112 | ERROR_IN_READING_FILE, //!< File found, loaded, but an error was encountered during processing. |
|---|
| 113 | FILE_REQUESTED, //!< Asynchronous file read has been requested, but returning immediately, keep polling plugin until file read has been completed. |
|---|
| 114 | INSUFFICIENT_MEMORY_TO_LOAD //!< File found but not loaded because estimated required memory surpasses available memory. |
|---|
| 115 | }; |
|---|
| 116 | |
|---|
| 117 | ReadResult(ReadStatus status=FILE_NOT_HANDLED):_status(status) {} |
|---|
| 118 | ReadResult(const std::string& m):_status(ERROR_IN_READING_FILE),_message(m) {} |
|---|
| 119 | ReadResult(osg::Object* obj, ReadStatus status=FILE_LOADED):_status(status),_object(obj) {} |
|---|
| 120 | |
|---|
| 121 | ReadResult(const ReadResult& rr):_status(rr._status),_message(rr._message),_object(rr._object) {} |
|---|
| 122 | ReadResult& operator = (const ReadResult& rr) { if (this==&rr) return *this; _status=rr._status; _message=rr._message;_object=rr._object; return *this; } |
|---|
| 123 | |
|---|
| 124 | osg::Object* getObject(); |
|---|
| 125 | osg::Image* getImage(); |
|---|
| 126 | osg::HeightField* getHeightField(); |
|---|
| 127 | osg::Node* getNode(); |
|---|
| 128 | osgDB::Archive* getArchive(); |
|---|
| 129 | osg::Shader* getShader(); |
|---|
| 130 | |
|---|
| 131 | bool validObject() { return _object.valid(); } |
|---|
| 132 | bool validImage() { return getImage()!=0; } |
|---|
| 133 | bool validHeightField() { return getHeightField()!=0; } |
|---|
| 134 | bool validNode() { return getNode()!=0; } |
|---|
| 135 | bool validArchive() { return getArchive()!=0; } |
|---|
| 136 | bool validShader() { return getShader()!=0; } |
|---|
| 137 | |
|---|
| 138 | osg::Object* takeObject(); |
|---|
| 139 | osg::Image* takeImage(); |
|---|
| 140 | osg::HeightField* takeHeightField(); |
|---|
| 141 | osg::Node* takeNode(); |
|---|
| 142 | osgDB::Archive* takeArchive(); |
|---|
| 143 | osg::Shader* takeShader(); |
|---|
| 144 | |
|---|
| 145 | std::string& message() { return _message; } |
|---|
| 146 | const std::string& message() const { return _message; } |
|---|
| 147 | |
|---|
| 148 | ReadStatus status() const { return _status; } |
|---|
| 149 | bool success() const { return _status==FILE_LOADED || _status==FILE_LOADED_FROM_CACHE ; } |
|---|
| 150 | bool loadedFromCache() const { return _status==FILE_LOADED_FROM_CACHE; } |
|---|
| 151 | bool error() const { return _status==ERROR_IN_READING_FILE; } |
|---|
| 152 | bool notHandled() const { return _status==FILE_NOT_HANDLED || _status==NOT_IMPLEMENTED; } |
|---|
| 153 | bool notFound() const { return _status==FILE_NOT_FOUND; } |
|---|
| 154 | bool notEnoughMemory() const { return _status==INSUFFICIENT_MEMORY_TO_LOAD; } |
|---|
| 155 | |
|---|
| 156 | protected: |
|---|
| 157 | |
|---|
| 158 | ReadStatus _status; |
|---|
| 159 | std::string _message; |
|---|
| 160 | osg::ref_ptr<osg::Object> _object; |
|---|
| 161 | |
|---|
| 162 | }; |
|---|
| 163 | |
|---|
| 164 | class WriteResult |
|---|
| 165 | { |
|---|
| 166 | public: |
|---|
| 167 | |
|---|
| 168 | enum WriteStatus |
|---|
| 169 | { |
|---|
| 170 | NOT_IMPLEMENTED, //!< write*() method not implemented in concrete ReaderWriter. |
|---|
| 171 | FILE_NOT_HANDLED, |
|---|
| 172 | FILE_SAVED, |
|---|
| 173 | ERROR_IN_WRITING_FILE |
|---|
| 174 | }; |
|---|
| 175 | |
|---|
| 176 | WriteResult(WriteStatus status=FILE_NOT_HANDLED):_status(status) {} |
|---|
| 177 | WriteResult(const std::string& m):_status(ERROR_IN_WRITING_FILE),_message(m) {} |
|---|
| 178 | |
|---|
| 179 | WriteResult(const WriteResult& rr):_status(rr._status),_message(rr._message) {} |
|---|
| 180 | WriteResult& operator = (const WriteResult& rr) { if (this==&rr) return *this; _status=rr._status; _message=rr._message; return *this; } |
|---|
| 181 | |
|---|
| 182 | std::string& message() { return _message; } |
|---|
| 183 | const std::string& message() const { return _message; } |
|---|
| 184 | |
|---|
| 185 | WriteStatus status() const { return _status; } |
|---|
| 186 | bool success() const { return _status==FILE_SAVED; } |
|---|
| 187 | bool error() const { return _status==ERROR_IN_WRITING_FILE; } |
|---|
| 188 | bool notHandled() const { return _status==FILE_NOT_HANDLED || _status==NOT_IMPLEMENTED; } |
|---|
| 189 | |
|---|
| 190 | protected: |
|---|
| 191 | |
|---|
| 192 | WriteStatus _status; |
|---|
| 193 | std::string _message; |
|---|
| 194 | }; |
|---|
| 195 | |
|---|
| 196 | enum ArchiveStatus |
|---|
| 197 | { |
|---|
| 198 | READ, |
|---|
| 199 | WRITE, |
|---|
| 200 | CREATE |
|---|
| 201 | }; |
|---|
| 202 | |
|---|
| 203 | typedef osgDB::Options Options; |
|---|
| 204 | |
|---|
| 205 | /** Determine if a file exists, normally the default implementation will be appropiate for local file access |
|---|
| 206 | * but with plugins like the libcurl based one it will return true if the file is accessible at the server. */ |
|---|
| 207 | virtual bool fileExists(const std::string& filename, const Options* options) const; |
|---|
| 208 | |
|---|
| 209 | /** Open an archive for reading, writing, or to create an empty archive for writing to.*/ |
|---|
| 210 | virtual ReadResult openArchive(const std::string& /*fileName*/,ArchiveStatus, unsigned int =4096, const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } |
|---|
| 211 | |
|---|
| 212 | /** Open an archive for reading.*/ |
|---|
| 213 | virtual ReadResult openArchive(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } |
|---|
| 214 | |
|---|
| 215 | virtual ReadResult readObject(const std::string& /*fileName*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } |
|---|
| 216 | virtual ReadResult readImage(const std::string& /*fileName*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } |
|---|
| 217 | virtual ReadResult readHeightField(const std::string& /*fileName*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } |
|---|
| 218 | virtual ReadResult readNode(const std::string& /*fileName*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } |
|---|
| 219 | virtual ReadResult readShader(const std::string& /*fileName*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } |
|---|
| 220 | |
|---|
| 221 | virtual WriteResult writeObject(const osg::Object& /*obj*/,const std::string& /*fileName*/,const Options* =NULL) const {return WriteResult(WriteResult::NOT_IMPLEMENTED); } |
|---|
| 222 | virtual WriteResult writeImage(const osg::Image& /*image*/,const std::string& /*fileName*/,const Options* =NULL) const {return WriteResult(WriteResult::NOT_IMPLEMENTED); } |
|---|
| 223 | virtual WriteResult writeHeightField(const osg::HeightField& /*heightField*/,const std::string& /*fileName*/,const Options* =NULL) const {return WriteResult(WriteResult::NOT_IMPLEMENTED); } |
|---|
| 224 | virtual WriteResult writeNode(const osg::Node& /*node*/,const std::string& /*fileName*/,const Options* =NULL) const { return WriteResult(WriteResult::NOT_IMPLEMENTED); } |
|---|
| 225 | virtual WriteResult writeShader(const osg::Shader& /*shader*/,const std::string& /*fileName*/,const Options* =NULL) const {return WriteResult(WriteResult::NOT_IMPLEMENTED); } |
|---|
| 226 | |
|---|
| 227 | virtual ReadResult readObject(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } |
|---|
| 228 | virtual ReadResult readImage(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } |
|---|
| 229 | virtual ReadResult readHeightField(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } |
|---|
| 230 | virtual ReadResult readNode(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } |
|---|
| 231 | virtual ReadResult readShader(std::istream& /*fin*/,const Options* =NULL) const { return ReadResult(ReadResult::NOT_IMPLEMENTED); } |
|---|
| 232 | |
|---|
| 233 | virtual WriteResult writeObject(const osg::Object& /*obj*/,std::ostream& /*fout*/,const Options* =NULL) const { return WriteResult(WriteResult::NOT_IMPLEMENTED); } |
|---|
| 234 | virtual WriteResult writeImage(const osg::Image& /*image*/,std::ostream& /*fout*/,const Options* =NULL) const { return WriteResult(WriteResult::NOT_IMPLEMENTED); } |
|---|
| 235 | virtual WriteResult writeHeightField(const osg::HeightField& /*heightField*/,std::ostream& /*fout*/,const Options* =NULL) const { return WriteResult(WriteResult::NOT_IMPLEMENTED); } |
|---|
| 236 | virtual WriteResult writeNode(const osg::Node& /*node*/,std::ostream& /*fout*/,const Options* =NULL) const { return WriteResult(WriteResult::NOT_IMPLEMENTED); } |
|---|
| 237 | virtual WriteResult writeShader(const osg::Shader& /*shader*/,std::ostream& /*fout*/,const Options* =NULL) const { return WriteResult(WriteResult::NOT_IMPLEMENTED); } |
|---|
| 238 | |
|---|
| 239 | /** Specify fmt string as a supported protocol. |
|---|
| 240 | * Please note, this method should usually only be used internally by subclasses of ReaderWriter, Only in special cases |
|---|
| 241 | * will a ReaderWriter implementation be able to handle a protocol format that it wasn't originally designed for. |
|---|
| 242 | * To know whether it's safe to inject a new protocol format into an existing ReaderWriter you will need to review |
|---|
| 243 | * the source code and dependencies of that ReaderWriter. */ |
|---|
| 244 | void supportsProtocol(const std::string& fmt, const std::string& description); |
|---|
| 245 | |
|---|
| 246 | /** Specify ext string as a supported file extension. |
|---|
| 247 | * Please note, this method should usually only be used internally by subclasses of ReaderWriter. Only in special cases |
|---|
| 248 | * will a ReaderWriter implementation be able to handle a file extension that it wasn't originally designed for. |
|---|
| 249 | * To know whether it's safe to inject a new file extension into an existing ReaderWriter you will need to review the |
|---|
| 250 | * the source code and dependencies of that ReaderWriter. */ |
|---|
| 251 | void supportsExtension(const std::string& ext, const std::string& description); |
|---|
| 252 | |
|---|
| 253 | /** Specify option string as a supported option string. |
|---|
| 254 | * Please note, this should usually only be used internally by subclasses of ReaderWriter. */ |
|---|
| 255 | void supportsOption(const std::string& opt, const std::string& description); |
|---|
| 256 | |
|---|
| 257 | protected: |
|---|
| 258 | |
|---|
| 259 | FormatDescriptionMap _supportedProtocols; |
|---|
| 260 | FormatDescriptionMap _supportedExtensions; |
|---|
| 261 | FormatDescriptionMap _supportedOptions; |
|---|
| 262 | }; |
|---|
| 263 | |
|---|
| 264 | } |
|---|
| 265 | |
|---|
| 266 | #endif // OSGDB_READERWRITER |
|---|