ReaderWriter 16 KB

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