1 #ifndef OSG2_BINARYSTREAMOPERATOR 2 #define OSG2_BINARYSTREAMOPERATOR 3 4 #include <osgDB/StreamOperator> 5 #include <osg/Types> 6 #include <vector> 7 8 9 class BinaryOutputIterator : public osgDB::OutputIterator 10 { 11 public: BinaryOutputIterator(std::ostream * ostream)12 BinaryOutputIterator( std::ostream* ostream ) { _out = ostream; } ~BinaryOutputIterator()13 virtual ~BinaryOutputIterator() {} 14 isBinary()15 virtual bool isBinary() const { return true; } 16 writeBool(bool b)17 virtual void writeBool( bool b ) 18 { char c = b?1:0; _out->write( &c, osgDB::CHAR_SIZE ); } 19 writeChar(char c)20 virtual void writeChar( char c ) 21 { _out->write( &c, osgDB::CHAR_SIZE ); } 22 writeUChar(unsigned char c)23 virtual void writeUChar( unsigned char c ) 24 { _out->write( (char*)&c, osgDB::CHAR_SIZE ); } 25 writeShort(short s)26 virtual void writeShort( short s ) 27 { _out->write( (char*)&s, osgDB::SHORT_SIZE ); } 28 writeUShort(unsigned short s)29 virtual void writeUShort( unsigned short s ) 30 { _out->write( (char*)&s, osgDB::SHORT_SIZE ); } 31 writeInt(int i)32 virtual void writeInt( int i ) 33 { _out->write( (char*)&i, osgDB::INT_SIZE ); } 34 writeUInt(unsigned int i)35 virtual void writeUInt( unsigned int i ) 36 { _out->write( (char*)&i, osgDB::INT_SIZE ); } 37 writeLong(long l)38 virtual void writeLong( long l ) 39 { 40 // On 64-bit systems a long may not be the same size as the file value 41 int32_t value=(int32_t)l; 42 _out->write( (char*)&value, osgDB::LONG_SIZE ); 43 } 44 writeULong(unsigned long l)45 virtual void writeULong( unsigned long l ) 46 { 47 // On 64-bit systems a long may not be the same size as the file value 48 uint32_t value=(int32_t)l; 49 _out->write( (char*)&value, osgDB::LONG_SIZE ); 50 } 51 writeInt64(int64_t ll)52 virtual void writeInt64( int64_t ll ) 53 {_out->write( (char*)&ll, osgDB::INT64_SIZE );} 54 writeUInt64(uint64_t ull)55 virtual void writeUInt64( uint64_t ull ) 56 {_out->write( (char*)&ull, osgDB::INT64_SIZE );} 57 writeInt(long long ll)58 virtual void writeInt( long long ll ) 59 { _out->write( (char*)&ll, osgDB::INT64_SIZE ); } 60 writeUInt(unsigned long long ull)61 virtual void writeUInt( unsigned long long ull ) 62 { _out->write( (char*)&ull, osgDB::INT64_SIZE ); } 63 writeFloat(float f)64 virtual void writeFloat( float f ) 65 { _out->write( (char*)&f, osgDB::FLOAT_SIZE ); } 66 writeDouble(double d)67 virtual void writeDouble( double d ) 68 { _out->write((char*)&d, osgDB::DOUBLE_SIZE); } 69 writeString(const std::string & s)70 virtual void writeString( const std::string& s ) 71 { 72 int size = s.size(); 73 _out->write( (char*)&size, osgDB::INT_SIZE ); 74 _out->write( s.c_str(), s.size() ); 75 } 76 writeStream(std::ostream & (*)(std::ostream &))77 virtual void writeStream( std::ostream& (* /*fn*/)(std::ostream&) ) {} 78 writeBase(std::ios_base & (*)(std::ios_base &))79 virtual void writeBase( std::ios_base& (* /*fn*/)(std::ios_base&) ) {} 80 writeGLenum(const osgDB::ObjectGLenum & value)81 virtual void writeGLenum( const osgDB::ObjectGLenum& value ) 82 { GLenum e = value.get(); _out->write((char*)&e, osgDB::GLENUM_SIZE); } 83 writeProperty(const osgDB::ObjectProperty & prop)84 virtual void writeProperty( const osgDB::ObjectProperty& prop ) 85 { if (prop._mapProperty) _out->write((char*)&(prop._value), osgDB::INT_SIZE); } 86 writeMark(const osgDB::ObjectMark & mark)87 virtual void writeMark( const osgDB::ObjectMark& mark ) 88 { 89 if ( _supportBinaryBrackets ) 90 { 91 if (getOutputStream() && getOutputStream()->getFileVersion() > 148) 92 { 93 if ( mark._name=="{" ) 94 { 95 uint64_t size = 0; 96 _beginPositions.push_back( _out->tellp() ); 97 _out->write( (char*)&size, osgDB::INT64_SIZE ); 98 } 99 else if ( mark._name=="}" && _beginPositions.size()>0 ) 100 { 101 std::streampos pos = _out->tellp(), beginPos = _beginPositions.back(); 102 _beginPositions.pop_back(); 103 _out->seekp( beginPos ); 104 105 std::streampos size64 = pos - beginPos; 106 uint64_t size = (uint64_t) size64; 107 _out->write( (char*)&size, osgDB::INT64_SIZE); 108 _out->seekp( pos ); 109 } 110 } 111 else 112 { 113 if ( mark._name=="{" ) 114 { 115 int size = 0; 116 _beginPositions.push_back( _out->tellp() ); 117 _out->write( (char*)&size, osgDB::INT_SIZE ); 118 } 119 else if ( mark._name=="}" && _beginPositions.size()>0 ) 120 { 121 std::streampos pos = _out->tellp(), beginPos = _beginPositions.back(); 122 _beginPositions.pop_back(); 123 _out->seekp( beginPos ); 124 125 std::streampos size64 = pos - beginPos; 126 int size = (int) size64; 127 _out->write( (char*)&size, osgDB::INT_SIZE); 128 _out->seekp( pos ); 129 } 130 } 131 } 132 } 133 writeCharArray(const char * s,unsigned int size)134 virtual void writeCharArray( const char* s, unsigned int size ) 135 { if ( size>0 ) _out->write( s, size ); } 136 writeWrappedString(const std::string & str)137 virtual void writeWrappedString( const std::string& str ) 138 { writeString( str ); } 139 140 protected: 141 std::vector<std::streampos> _beginPositions; 142 }; 143 144 class BinaryInputIterator : public osgDB::InputIterator 145 { 146 public: BinaryInputIterator(std::istream * istream,int byteSwap)147 BinaryInputIterator( std::istream* istream, int byteSwap ) 148 { 149 _in = istream; 150 setByteSwap(byteSwap); 151 } 152 ~BinaryInputIterator()153 virtual ~BinaryInputIterator() {} 154 isBinary()155 virtual bool isBinary() const { return true; } 156 readBool(bool & b)157 virtual void readBool( bool& b ) 158 { 159 char c = 0; 160 _in->read( &c, osgDB::CHAR_SIZE ); 161 b = (c!=0); 162 } 163 readChar(char & c)164 virtual void readChar( char& c ) 165 { _in->read( &c, osgDB::CHAR_SIZE ); } 166 readSChar(signed char & c)167 virtual void readSChar( signed char& c ) 168 { _in->read( (char*)&c, osgDB::CHAR_SIZE ); } 169 readUChar(unsigned char & c)170 virtual void readUChar( unsigned char& c ) 171 { _in->read( (char*)&c, osgDB::CHAR_SIZE ); } 172 readShort(short & s)173 virtual void readShort( short& s ) 174 { 175 _in->read( (char*)&s, osgDB::SHORT_SIZE ); 176 if ( _byteSwap ) osg::swapBytes( (char*)&s, osgDB::SHORT_SIZE ); 177 } 178 readUShort(unsigned short & s)179 virtual void readUShort( unsigned short& s ) 180 { 181 _in->read( (char*)&s, osgDB::SHORT_SIZE ); 182 if ( _byteSwap ) osg::swapBytes( (char*)&s, osgDB::SHORT_SIZE ); 183 } 184 readInt(int & i)185 virtual void readInt( int& i ) 186 { 187 _in->read( (char*)&i, osgDB::INT_SIZE ); 188 if ( _byteSwap ) osg::swapBytes( (char*)&i, osgDB::INT_SIZE ); 189 } 190 readUInt(unsigned int & i)191 virtual void readUInt( unsigned int& i ) 192 { 193 _in->read( (char*)&i, osgDB::INT_SIZE ); 194 if ( _byteSwap ) osg::swapBytes( (char*)&i, osgDB::INT_SIZE ); 195 } 196 readLong(long & l)197 virtual void readLong( long& l ) 198 { 199 // On 64-bit systems a long may not be the same size as the file value 200 int32_t value; 201 _in->read( (char*)&value, osgDB::LONG_SIZE ); 202 if ( _byteSwap ) osg::swapBytes( (char*)&value, osgDB::LONG_SIZE ); 203 l = (long)value; 204 } 205 readULong(unsigned long & l)206 virtual void readULong( unsigned long& l ) 207 { 208 uint32_t value; 209 _in->read( (char*)&value, osgDB::LONG_SIZE ); 210 if ( _byteSwap ) osg::swapBytes( (char*)&value, osgDB::LONG_SIZE ); 211 l = (unsigned long)value; 212 } 213 readFloat(float & f)214 virtual void readFloat( float& f ) 215 { 216 _in->read( (char*)&f, osgDB::FLOAT_SIZE ); 217 if ( _byteSwap ) osg::swapBytes( (char*)&f, osgDB::FLOAT_SIZE ); 218 } 219 readDouble(double & d)220 virtual void readDouble( double& d ) 221 { 222 _in->read( (char*)&d, osgDB::DOUBLE_SIZE ); 223 if ( _byteSwap ) osg::swapBytes( (char*)&d, osgDB::DOUBLE_SIZE ); 224 } 225 readString(std::string & s)226 virtual void readString( std::string& s ) 227 { 228 int size = 0; 229 readInt( size ); 230 if ( size>0 ) 231 { 232 s.resize( size ); 233 _in->read( (char*)s.c_str(), size ); 234 } 235 else if ( size<0 ) 236 { 237 throwException( "InputStream::readString() error, negative string size read." ); 238 } 239 } 240 readStream(std::istream & (*)(std::istream &))241 virtual void readStream( std::istream& (* /*fn*/)(std::istream&) ) {} 242 readBase(std::ios_base & (*)(std::ios_base &))243 virtual void readBase( std::ios_base& (* /*fn*/)(std::ios_base&) ) {} 244 readGLenum(osgDB::ObjectGLenum & value)245 virtual void readGLenum( osgDB::ObjectGLenum& value ) 246 { 247 GLenum e = 0; 248 _in->read( (char*)&e, osgDB::GLENUM_SIZE ); 249 if ( _byteSwap ) osg::swapBytes( (char*)&e, osgDB::GLENUM_SIZE ); 250 value.set( e ); 251 } 252 readProperty(osgDB::ObjectProperty & prop)253 virtual void readProperty( osgDB::ObjectProperty& prop ) 254 { 255 int value = 0; 256 if ( prop._mapProperty ) 257 { 258 _in->read( (char*)&value, osgDB::INT_SIZE ); 259 if ( _byteSwap ) osg::swapBytes( (char*)&value, osgDB::INT_SIZE ); 260 } 261 prop.set( value ); 262 } 263 readMark(osgDB::ObjectMark & mark)264 virtual void readMark( osgDB::ObjectMark& mark ) 265 { 266 if ( _supportBinaryBrackets ) 267 { 268 if ( mark._name=="{" ) 269 { 270 _beginPositions.push_back( _in->tellg() ); 271 272 // since version 149 (osg version > 3.5.6) size is expressed 273 // on 8 bytes rather than 4 bytes, 274 // to accommodate any block size. 275 if (getInputStream() && getInputStream()->getFileVersion() > 148) 276 { 277 uint64_t size = 0; 278 _in->read( (char*)&size, osgDB::INT64_SIZE); 279 if ( _byteSwap ) osg::swapBytes( (char*)&size, osgDB::INT64_SIZE); 280 _blockSizes.push_back( size ); 281 } 282 else 283 { 284 int size = 0; 285 _in->read( (char*)&size, osgDB::INT_SIZE); 286 if ( _byteSwap ) osg::swapBytes( (char*)&size, osgDB::INT_SIZE); 287 _blockSizes.push_back( size ); 288 } 289 } 290 else if ( mark._name=="}" && _beginPositions.size()>0 ) 291 { 292 _beginPositions.pop_back(); 293 _blockSizes.pop_back(); 294 } 295 } 296 } 297 readCharArray(char * s,unsigned int size)298 virtual void readCharArray( char* s, unsigned int size ) 299 { if ( size>0 ) _in->read( s, size ); } 300 readWrappedString(std::string & str)301 virtual void readWrappedString( std::string& str ) 302 { readString( str ); } 303 advanceToCurrentEndBracket()304 virtual void advanceToCurrentEndBracket() 305 { 306 if ( _supportBinaryBrackets && _beginPositions.size()>0 ) 307 { 308 std::streampos position(_beginPositions.back()); 309 position += _blockSizes.back(); 310 _in->seekg( position ); 311 _beginPositions.pop_back(); 312 _blockSizes.pop_back(); 313 } 314 } 315 316 protected: 317 std::vector<std::streampos> _beginPositions; 318 std::vector<std::streampos> _blockSizes; 319 }; 320 321 #endif 322