OutputStream 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 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. // Written by Wang Rui, (C) 2010
  14. #ifndef OSGDB_OUTPUTSTREAM
  15. #define OSGDB_OUTPUTSTREAM
  16. #include <osg/Version>
  17. #include <osg/Vec2>
  18. #include <osg/Vec3>
  19. #include <osg/Vec4>
  20. #include <osg/Quat>
  21. #include <osg/Matrix>
  22. #include <osg/BoundingBox>
  23. #include <osg/BoundingSphere>
  24. #include <osg/Array>
  25. #include <osg/PrimitiveSet>
  26. #include <osgDB/ReaderWriter>
  27. #include <osgDB/StreamOperator>
  28. #include <iostream>
  29. #include <sstream>
  30. namespace osgDB
  31. {
  32. class OutputException : public osg::Referenced
  33. {
  34. public:
  35. OutputException( const std::vector<std::string>& fields, const std::string& err ) : _error(err)
  36. {
  37. for ( unsigned int i=0; i<fields.size(); ++i )
  38. {
  39. _field += fields[i];
  40. _field += " ";
  41. }
  42. }
  43. const std::string& getField() const { return _field; }
  44. const std::string& getError() const { return _error; }
  45. protected:
  46. std::string _field;
  47. std::string _error;
  48. };
  49. class OSGDB_EXPORT OutputStream
  50. {
  51. public:
  52. typedef std::map<const osg::Array*, unsigned int> ArrayMap;
  53. typedef std::map<const osg::Object*, unsigned int> ObjectMap;
  54. enum WriteType
  55. {
  56. WRITE_UNKNOWN = 0,
  57. WRITE_SCENE,
  58. WRITE_IMAGE,
  59. WRITE_OBJECT
  60. };
  61. enum WriteImageHint
  62. {
  63. WRITE_USE_IMAGE_HINT = 0, /*!< Use image hint, write inline data or use external */
  64. WRITE_USE_EXTERNAL, /*!< Use external file on disk and write only the filename */
  65. WRITE_INLINE_DATA, /*!< Write Image::data() to stream */
  66. WRITE_INLINE_FILE, /*!< Write the image file itself to stream */
  67. WRITE_EXTERNAL_FILE /*!< Write Image::data() to disk and use it as external file */
  68. };
  69. OutputStream( const osgDB::Options* options );
  70. virtual ~OutputStream();
  71. void setFileVersion( const std::string& d, int v );
  72. int getFileVersion( const std::string& d=std::string() ) const;
  73. bool isBinary() const { return _out->isBinary(); }
  74. const std::string& getSchemaName() const { return _schemaName; }
  75. const osgDB::Options* getOptions() const { return _options.get(); }
  76. void setWriteImageHint( WriteImageHint hint ) { _writeImageHint = hint; }
  77. WriteImageHint getWriteImageHint() const { return _writeImageHint; }
  78. // Serialization related functions
  79. OutputStream& operator<<( bool b ) { _out->writeBool(b); return *this; }
  80. OutputStream& operator<<( char c ) { _out->writeChar(c); return *this; }
  81. OutputStream& operator<<( signed char c) { _out->writeChar(c); return *this; }
  82. OutputStream& operator<<( unsigned char c ) { _out->writeUChar(c); return *this; }
  83. OutputStream& operator<<( short s ) { _out->writeShort(s); return *this; }
  84. OutputStream& operator<<( unsigned short s ) { _out->writeUShort(s); return *this; }
  85. OutputStream& operator<<( int i ) { _out->writeInt(i); return *this; }
  86. OutputStream& operator<<( unsigned int i ) { _out->writeUInt(i); return *this; }
  87. OutputStream& operator<<( long l ) { _out->writeLong(l); return *this; }
  88. OutputStream& operator<<( unsigned long l ) { _out->writeULong(l); return *this; }
  89. OutputStream& operator<<( float f ) { _out->writeFloat(f); return *this; }
  90. OutputStream& operator<<( double d ) { _out->writeDouble(d); return *this; }
  91. OutputStream& operator<<( long long ll ) { _out->writeInt64(ll); return *this; }
  92. OutputStream& operator<<( unsigned long long ull ) { _out->writeUInt64(ull); return *this; }
  93. OutputStream& operator<<( const std::string& s ) { _out->writeString(s); return *this; }
  94. OutputStream& operator<<( const char* s ) { _out->writeString(s); return *this; }
  95. OutputStream& operator<<( std::ostream& (*fn)(std::ostream&) ) { _out->writeStream(fn); return *this; }
  96. OutputStream& operator<<( std::ios_base& (*fn)(std::ios_base&) ) { _out->writeBase(fn); return *this; }
  97. OutputStream& operator<<( const ObjectGLenum& value ) { _out->writeGLenum(value); return *this; }
  98. OutputStream& operator<<( const ObjectProperty& prop ) { _out->writeProperty(prop); return *this; }
  99. OutputStream& operator<<( const ObjectMark& mark ) { _out->writeMark(mark); return *this; }
  100. OutputStream& operator<<( const osg::Vec2b& v );
  101. OutputStream& operator<<( const osg::Vec3b& v );
  102. OutputStream& operator<<( const osg::Vec4b& v );
  103. OutputStream& operator<<( const osg::Vec2ub& v );
  104. OutputStream& operator<<( const osg::Vec3ub& v );
  105. OutputStream& operator<<( const osg::Vec4ub& v );
  106. OutputStream& operator<<( const osg::Vec2s& v );
  107. OutputStream& operator<<( const osg::Vec3s& v );
  108. OutputStream& operator<<( const osg::Vec4s& v );
  109. OutputStream& operator<<( const osg::Vec2us& v );
  110. OutputStream& operator<<( const osg::Vec3us& v );
  111. OutputStream& operator<<( const osg::Vec4us& v );
  112. OutputStream& operator<<( const osg::Vec2i& v );
  113. OutputStream& operator<<( const osg::Vec3i& v );
  114. OutputStream& operator<<( const osg::Vec4i& v );
  115. OutputStream& operator<<( const osg::Vec2ui& v );
  116. OutputStream& operator<<( const osg::Vec3ui& v );
  117. OutputStream& operator<<( const osg::Vec4ui& v );
  118. OutputStream& operator<<( const osg::Vec2f& v );
  119. OutputStream& operator<<( const osg::Vec3f& v );
  120. OutputStream& operator<<( const osg::Vec4f& v );
  121. OutputStream& operator<<( const osg::Vec2d& v );
  122. OutputStream& operator<<( const osg::Vec3d& v );
  123. OutputStream& operator<<( const osg::Vec4d& v );
  124. OutputStream& operator<<( const osg::Quat& q );
  125. OutputStream& operator<<( const osg::Plane& p );
  126. OutputStream& operator<<( const osg::Matrixf& mat );
  127. OutputStream& operator<<( const osg::Matrixd& mat );
  128. OutputStream& operator<<( const osg::BoundingBoxf& bb );
  129. OutputStream& operator<<( const osg::BoundingBoxd& bb );
  130. OutputStream& operator<<( const osg::BoundingSpheref& bb );
  131. OutputStream& operator<<( const osg::BoundingSphered& bb );
  132. OutputStream& operator<<( const osg::Image* img ) { writeImage(img); return *this; }
  133. OutputStream& operator<<( const osg::Array* a ) { if (_targetFileVersion >= 112) writeObject(a); else writeArray(a); return *this; }
  134. OutputStream& operator<<( const osg::PrimitiveSet* p ) { if (_targetFileVersion >= 112) writeObject(p); else writePrimitiveSet(p); return *this; }
  135. OutputStream& operator<<( const osg::Object* obj ) { writeObject(obj); return *this; }
  136. OutputStream& operator<<( const osg::ref_ptr<osg::Image>& ptr ) { writeImage(ptr.get()); return *this; }
  137. OutputStream& operator<<( const osg::ref_ptr<osg::Array>& ptr ) { if (_targetFileVersion >= 112) writeObject(ptr.get()); else writeArray(ptr.get()); return *this; }
  138. OutputStream& operator<<( const osg::ref_ptr<osg::PrimitiveSet>& ptr ) { if (_targetFileVersion >= 112) writeObject(ptr.get()); else writePrimitiveSet(ptr.get()); return *this; }
  139. template<typename T> OutputStream& operator<<( const osg::ref_ptr<T>& ptr ) { writeObject(ptr.get()); return *this; }
  140. // Convenient methods for writing
  141. void writeWrappedString( const std::string& str ) { _out->writeWrappedString(str); }
  142. void writeCharArray( const char* s, unsigned int size ) { _out->writeCharArray(s, size); }
  143. // method for converting all data structure sizes to unsigned int to ensure architecture portability.
  144. template<typename T>
  145. void writeSize(T size) { *this<<static_cast<unsigned int>(size); }
  146. // Global writing functions
  147. void writeArray( const osg::Array* a );
  148. void writePrimitiveSet( const osg::PrimitiveSet* p );
  149. void writeImage( const osg::Image* img );
  150. void writeObject( const osg::Object* obj );
  151. void writeObjectFields( const osg::Object* obj );
  152. void writeObjectFields( const osg::Object* obj, const std::string& compoundName );
  153. /// set an output iterator, used directly when not using OutputStream with a traditional file related stream.
  154. void setOutputIterator( OutputIterator* oi ) { _out = oi; }
  155. /// start writing to OutputStream treating it as a traditional file related stream, handles headers and versioning
  156. void start( OutputIterator* outIterator, WriteType type );
  157. void compress( std::ostream* ostream );
  158. // Schema handlers
  159. void writeSchema( std::ostream& fout );
  160. // Exception handlers
  161. inline void throwException( const std::string& msg );
  162. const OutputException* getException() const { return _exception.get(); }
  163. // Property & mask variables
  164. ObjectProperty PROPERTY;
  165. ObjectMark BEGIN_BRACKET;
  166. ObjectMark END_BRACKET;
  167. protected:
  168. template<typename T>
  169. void writeArrayImplementation( const T*, int write_size, unsigned int numInRow=1 );
  170. unsigned int findOrCreateArrayID( const osg::Array* array, bool& newID );
  171. unsigned int findOrCreateObjectID( const osg::Object* obj, bool& newID );
  172. ArrayMap _arrayMap;
  173. ObjectMap _objectMap;
  174. typedef std::map<std::string, int> VersionMap;
  175. VersionMap _domainVersionMap;
  176. WriteImageHint _writeImageHint;
  177. bool _useSchemaData;
  178. bool _useRobustBinaryFormat;
  179. typedef std::map<std::string, std::string> SchemaMap;
  180. SchemaMap _inbuiltSchemaMap;
  181. std::vector<std::string> _fields;
  182. std::string _schemaName;
  183. std::string _compressorName;
  184. std::stringstream _compressSource;
  185. osg::ref_ptr<OutputIterator> _out;
  186. osg::ref_ptr<OutputException> _exception;
  187. osg::ref_ptr<const osgDB::Options> _options;
  188. int _targetFileVersion;
  189. };
  190. void OutputStream::throwException( const std::string& msg )
  191. {
  192. _exception = new OutputException(_fields, msg);
  193. }
  194. }
  195. #endif