From a520e8b6bdbbf409e106c811e60e0206c04c2af1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 25 Jan 2010 11:03:21 +0000 Subject: [PATCH] From Wang Rui, refactored the InputStream/OutputStream operations so that the binar/ascii foramts are implemented via subclasses. --- include/osgDB/DataTypes | 16 +- include/osgDB/InputStream | 289 +++------------------- include/osgDB/ObjectWrapper | 4 +- include/osgDB/OutputStream | 260 ++----------------- include/osgDB/Serializer | 4 +- include/osgDB/StreamOperator | 91 +++++++ src/osgDB/CMakeLists.txt | 1 + src/osgDB/InputStream.cpp | 109 ++------ src/osgDB/OutputStream.cpp | 73 +----- src/osgPlugins/osg/AsciiStreamOperator.h | 217 ++++++++++++++++ src/osgPlugins/osg/BinaryStreamOperator.h | 184 ++++++++++++++ src/osgPlugins/osg/ReaderWriterOSG2.cpp | 59 ++++- 12 files changed, 647 insertions(+), 660 deletions(-) create mode 100755 include/osgDB/StreamOperator create mode 100644 src/osgPlugins/osg/AsciiStreamOperator.h create mode 100644 src/osgPlugins/osg/BinaryStreamOperator.h diff --git a/include/osgDB/DataTypes b/include/osgDB/DataTypes index 6e74793e7..b53575fd9 100644 --- a/include/osgDB/DataTypes +++ b/include/osgDB/DataTypes @@ -12,8 +12,8 @@ */ // Written by Wang Rui, (C) 2010 -#ifndef H_DATATYPES -#define H_DATATYPES +#ifndef OSGDB_DATATYPES +#define OSGDB_DATATYPES #include @@ -92,12 +92,12 @@ struct ObjectProperty ObjectProperty( const ObjectProperty& copy ) : _name(copy._name), _value(copy._value), _mapProperty(copy._mapProperty) {} - ObjectProperty& proto( const char* name ) - { _name = name; return *this; } - - void set( int v ) { _value = v; } - int get() const { return _value; } - + ObjectProperty& proto( const char* name ) + { _name = name; return *this; } + + void set( int v ) { _value = v; } + int get() const { return _value; } + std::string _name; int _value; bool _mapProperty; diff --git a/include/osgDB/InputStream b/include/osgDB/InputStream index 9ed6497bc..5a0a06133 100644 --- a/include/osgDB/InputStream +++ b/include/osgDB/InputStream @@ -12,8 +12,8 @@ */ // Written by Wang Rui, (C) 2010 -#ifndef H_INPUTSTREAM -#define H_INPUTSTREAM +#ifndef OSGDB_INPUTSTREAM +#define OSGDB_INPUTSTREAM #include #include @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include @@ -51,12 +51,6 @@ public: typedef std::map< unsigned int, osg::ref_ptr > ArrayMap; typedef std::map< unsigned int, osg::ref_ptr > IdentifierMap; - enum ReadMode - { - READ_BINARY = 0, - READ_ASCII - }; - enum ReadType { READ_UNKNOWN = 0, @@ -64,28 +58,32 @@ public: READ_IMAGE }; - InputStream( std::istream* istream, const osgDB::Options* options ); + InputStream( const osgDB::Options* options ); virtual ~InputStream(); - bool isBinary() const { return _readMode==READ_BINARY; } + bool isBinary() const { return _in->isBinary(); } bool getUseFloatMatrix() const { return _useFloatMatrix; } // Serialization related functions - inline InputStream& operator>>( bool& b ); - inline InputStream& operator>>( char& c ); - inline InputStream& operator>>( signed char& c ); - inline InputStream& operator>>( unsigned char& c ); - inline InputStream& operator>>( short& s ); - inline InputStream& operator>>( unsigned short& s ); - inline InputStream& operator>>( int& i ); - inline InputStream& operator>>( unsigned int& i ); - inline InputStream& operator>>( long& l ); - inline InputStream& operator>>( unsigned long& l ); - inline InputStream& operator>>( float& f ); - inline InputStream& operator>>( double& d ); - inline InputStream& operator>>( std::string& s ); - inline InputStream& operator>>( std::istream& (*fn)(std::istream&) ); - inline InputStream& operator>>( std::ios_base& (*fn)(std::ios_base&) ); + InputStream& operator>>( bool& b ) { _in->readBool(b); return *this; } + InputStream& operator>>( char& c ) { _in->readChar(c); return *this; } + InputStream& operator>>( signed char& c ) { _in->readSChar(c); return *this; } + InputStream& operator>>( unsigned char& c ) { _in->readUChar(c); return *this; } + InputStream& operator>>( short& s ) { _in->readShort(s); return *this; } + InputStream& operator>>( unsigned short& s ) { _in->readUShort(s); return *this; } + InputStream& operator>>( int& i ) { _in->readInt(i); return *this; } + InputStream& operator>>( unsigned int& i ) { _in->readUInt(i); return *this; } + InputStream& operator>>( long& l ) { _in->readLong(l); return *this; } + InputStream& operator>>( unsigned long& l ) { _in->readULong(l); return *this; } + InputStream& operator>>( float& f ) { _in->readFloat(f); return *this; } + InputStream& operator>>( double& d ) { _in->readDouble(d); return *this; } + InputStream& operator>>( std::string& s ) { _in->readString(s); return *this; } + InputStream& operator>>( std::istream& (*fn)(std::istream&) ) { _in->readStream(fn); return *this; } + InputStream& operator>>( std::ios_base& (*fn)(std::ios_base&) ) { _in->readBase(fn); return *this; } + + InputStream& operator>>( ObjectGLenum& value ) { _in->readGLenum(value); return *this; } + InputStream& operator>>( ObjectProperty& prop ) { _in->readProperty(prop); return *this; } + InputStream& operator>>( ObjectMark& mark ) { _in->readMark(mark); return *this; } InputStream& operator>>( osg::Vec2b& v ); InputStream& operator>>( osg::Vec3b& v ); @@ -117,15 +115,11 @@ public: template InputStream& operator>>( osg::ref_ptr& ptr ) { ptr = static_cast(readObject()); return *this; } - InputStream& operator>>( ObjectGLenum& value ); - InputStream& operator>>( ObjectProperty& prop ); - InputStream& operator>>( ObjectMark& mark ); - // Convenient methods for reading inline bool matchString( const std::string& str ); inline void advanceToCurrentEndBracket(); inline void readWrappedString( std::string& str ); - inline void readCharArray( char* s, unsigned int size ); + void readCharArray( char* s, unsigned int size ) { _in->readCharArray(s, size); } // Global reading functions osg::Array* readArray(); @@ -133,7 +127,7 @@ public: osg::Image* readImage(); osg::Object* readObject( osg::Object* existingObj=0 ); - ReadType start(); + ReadType start( InputIterator* ); void decompress(); // Schema handlers @@ -150,228 +144,19 @@ protected: ArrayMap _arrayMap; IdentifierMap _identifierMap; - ReadMode _readMode; int _byteSwap; bool _useFloatMatrix; std::string _currentField; - std::istream* _in; + InputIterator* _in; }; -// INLINE METHODS - -InputStream& InputStream::operator>>( bool& b ) -{ - if ( isBinary() ) - { - char c = 0; - _in->read( &c, CHAR_SIZE ); checkStream(); - b = (c!=0); - } - else - { - std::string boolString; - *_in >> boolString; checkStream(); - if ( boolString=="TRUE" ) b = true; - else b = false; - } - return *this; -} - -InputStream& InputStream::operator>>( char& c ) -{ - if ( isBinary() ) - { - _in->read( &c, CHAR_SIZE ); checkStream(); - } - else - { - short s = 0; - *_in >> s; checkStream(); - c = (char)s; - } - return *this; -} - -InputStream& InputStream::operator>>( signed char& c ) -{ - if ( isBinary() ) - { - _in->read( (char*)&c, CHAR_SIZE ); checkStream(); - } - else - { - short s = 0; - *_in >> s; checkStream(); - c = (signed char)s; - } - return *this; -} - -InputStream& InputStream::operator>>( unsigned char& c ) -{ - if ( isBinary() ) - { - _in->read( (char*)&c, CHAR_SIZE ); checkStream(); - } - else - { - unsigned short s = 0; - *_in >> s; checkStream(); - c = (unsigned char)s; - } - return *this; -} - -InputStream& InputStream::operator>>( short& s ) -{ - if ( isBinary() ) - { - _in->read( (char*)&s, SHORT_SIZE ); checkStream(); - if ( _byteSwap ) osg::swapBytes( (char*)&s, SHORT_SIZE ); - } - else - { - *_in >> s; checkStream(); - } - return *this; -} - -InputStream& InputStream::operator>>( unsigned short& s ) -{ - if ( isBinary() ) - { - _in->read( (char*)&s, SHORT_SIZE ); checkStream(); - if ( _byteSwap ) osg::swapBytes( (char*)&s, SHORT_SIZE ); - } - else - { - *_in >> s; checkStream(); - } - return *this; -} - -InputStream& InputStream::operator>>( int& i ) -{ - if ( isBinary() ) - { - _in->read( (char*)&i, INT_SIZE ); checkStream(); - if ( _byteSwap ) osg::swapBytes( (char*)&i, INT_SIZE ); - } - else - { - *_in >> i; checkStream(); - } - return *this; -} - -InputStream& InputStream::operator>>( unsigned int& i ) -{ - if ( isBinary() ) - { - _in->read( (char*)&i, INT_SIZE ); checkStream(); - if ( _byteSwap ) osg::swapBytes( (char*)&i, INT_SIZE ); - } - else - { - *_in >> i; checkStream(); - } - return *this; -} - -InputStream& InputStream::operator>>( long& l ) -{ - if ( isBinary() ) - { - _in->read( (char*)&l, LONG_SIZE ); checkStream(); - if ( _byteSwap ) osg::swapBytes( (char*)&l, LONG_SIZE ); - } - else - { - *_in >> l; checkStream(); - } - return *this; -} - -InputStream& InputStream::operator>>( unsigned long& l ) -{ - if ( isBinary() ) - { - _in->read( (char*)&l, LONG_SIZE ); checkStream(); - if ( _byteSwap ) osg::swapBytes( (char*)&l, LONG_SIZE ); - } - else - { - *_in >> l; checkStream(); - } - return *this; -} - -InputStream& InputStream::operator>>( float& f ) -{ - if ( isBinary() ) - { - _in->read( (char*)&f, FLOAT_SIZE ); checkStream(); - if ( _byteSwap ) osg::swapBytes( (char*)&f, FLOAT_SIZE ); - } - else - { - *_in >> f; checkStream(); - } - return *this; -} - -InputStream& InputStream::operator>>( double& d ) -{ - if ( isBinary() ) - { - _in->read( (char*)&d, DOUBLE_SIZE ); checkStream(); - if ( _byteSwap ) osg::swapBytes( (char*)&d, DOUBLE_SIZE ); - } - else - { - *_in >> d; checkStream(); - } - return *this; -} - -InputStream& InputStream::operator>>( std::string& s ) -{ - if ( isBinary() ) - { - int size = 0; *this >> size; - if ( size ) - { - s.resize( size ); - _in->read( (char*)s.c_str(), size ); checkStream(); - } - } - else - { - *_in >> s; checkStream(); - } - return *this; -} - -InputStream& InputStream::operator>>( std::istream& (*fn)(std::istream&) ) -{ - if ( !isBinary() ) *_in >> fn; - return *this; -} - -InputStream& InputStream::operator>>( std::ios_base& (*fn)(std::ios_base&) ) -{ - if ( !isBinary() ) *_in >> fn; - return *this; -} - bool InputStream::matchString( const std::string& str ) { if ( !isBinary() ) { - std::string s; - *_in >> s; checkStream(); + std::string s; *this >> s; if ( s==str ) return true; - else _in->seekg( -(int)(s.length()), std::ios::cur ); + else _in->getStream()->seekg( -(int)(s.length()), std::ios::cur ); } return false; } @@ -383,10 +168,10 @@ void InputStream::advanceToCurrentEndBracket() std::string passString; unsigned int blocks = 0; - while ( !_in->eof() ) + while ( !_in->getStream()->eof() ) { passString.clear(); - *_in >> passString; + *this >> passString; if ( passString=="}" ) { @@ -410,7 +195,7 @@ void InputStream::readWrappedString( std::string& str ) char ch; do { - _in->get( ch ); checkStream(); + _in->getStream()->get( ch ); checkStream(); str.append( 1, ch ); } while ( ch!='\"' ); } @@ -419,17 +204,9 @@ void InputStream::readWrappedString( std::string& str ) } } -void InputStream::readCharArray( char* s, unsigned int size ) -{ - if ( size>0 ) - { - _in->read( s, size ); checkStream(); - } -} - void InputStream::checkStream() const { - if ( _in->rdstate()&_in->failbit ) + if ( _in->isFailed() ) throw InputException(_currentField, "InputStream: Failed to read from stream."); } diff --git a/include/osgDB/ObjectWrapper b/include/osgDB/ObjectWrapper index c10dfb4ee..23ccc424e 100644 --- a/include/osgDB/ObjectWrapper +++ b/include/osgDB/ObjectWrapper @@ -12,8 +12,8 @@ */ // Written by Wang Rui, (C) 2010 -#ifndef H_OBJECTWRAPPER -#define H_OBJECTWRAPPER +#ifndef OSGDB_OBJECTWRAPPER +#define OSGDB_OBJECTWRAPPER #include diff --git a/include/osgDB/OutputStream b/include/osgDB/OutputStream index 3c46fef57..aa1c9974b 100644 --- a/include/osgDB/OutputStream +++ b/include/osgDB/OutputStream @@ -12,8 +12,8 @@ */ // Written by Wang Rui, (C) 2010 -#ifndef H_OUTPUTSTREAM -#define H_OUTPUTSTREAM +#ifndef OSGDB_OUTPUTSTREAM +#define OSGDB_OUTPUTSTREAM #include #include @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include @@ -50,12 +50,6 @@ public: typedef std::map ArrayMap; typedef std::map ObjectMap; - enum WriteMode - { - WRITE_BINARY = 0, - WRITE_ASCII - }; - enum WriteType { WRITE_UNKNOWN = 0, @@ -72,29 +66,33 @@ public: WRITE_EXTERNAL_FILE /*!< Write Image::data() to disk and use it as external file */ }; - OutputStream( std::ostream* ostream, const osgDB::Options* options ); + OutputStream( const osgDB::Options* options ); virtual ~OutputStream(); - bool isBinary() const { return _writeMode==WRITE_BINARY; } + bool isBinary() const { return _out->isBinary(); } void setWriteImageHint( WriteImageHint hint ) { _writeImageHint = hint; } WriteImageHint getWriteImageHint() const { return _writeImageHint; } // Serialization related functions - inline OutputStream& operator<<( bool b ); - inline OutputStream& operator<<( char c ); - inline OutputStream& operator<<( unsigned char c ); - inline OutputStream& operator<<( short s ); - inline OutputStream& operator<<( unsigned short s ); - inline OutputStream& operator<<( int i ); - inline OutputStream& operator<<( unsigned int i ); - inline OutputStream& operator<<( long l ); - inline OutputStream& operator<<( unsigned long l ); - inline OutputStream& operator<<( float f ); - inline OutputStream& operator<<( double d ); - inline OutputStream& operator<<( const std::string& s ); - inline OutputStream& operator<<( std::ostream& (*fn)(std::ostream&) ); - inline OutputStream& operator<<( std::ios_base& (*fn)(std::ios_base&) ); + OutputStream& operator<<( bool b ) { _out->writeBool(b); return *this; } + OutputStream& operator<<( char c ) { _out->writeChar(c); return *this; } + OutputStream& operator<<( unsigned char c ) { _out->writeUChar(c); return *this; } + OutputStream& operator<<( short s ) { _out->writeShort(s); return *this; } + OutputStream& operator<<( unsigned short s ) { _out->writeUShort(s); return *this; } + OutputStream& operator<<( int i ) { _out->writeInt(i); return *this; } + OutputStream& operator<<( unsigned int i ) { _out->writeUInt(i); return *this; } + OutputStream& operator<<( long l ) { _out->writeLong(l); return *this; } + OutputStream& operator<<( unsigned long l ) { _out->writeULong(l); return *this; } + OutputStream& operator<<( float f ) { _out->writeFloat(f); return *this; } + OutputStream& operator<<( double d ) { _out->writeDouble(d); return *this; } + OutputStream& operator<<( const std::string& s ) { _out->writeString(s); return *this; } + OutputStream& operator<<( std::ostream& (*fn)(std::ostream&) ) { _out->writeStream(fn); return *this; } + OutputStream& operator<<( std::ios_base& (*fn)(std::ios_base&) ) { _out->writeBase(fn); return *this; } + + OutputStream& operator<<( const ObjectGLenum& value ) { _out->writeGLenum(value); return *this; } + OutputStream& operator<<( const ObjectProperty& prop ) { _out->writeProperty(prop); return *this; } + OutputStream& operator<<( const ObjectMark& mark ) { _out->writeMark(mark); return *this; } OutputStream& operator<<( const osg::Vec2b& v ); OutputStream& operator<<( const osg::Vec3b& v ); @@ -126,13 +124,9 @@ public: template OutputStream& operator<<( const osg::ref_ptr& ptr ) { writeObject(ptr.get()); return *this; } - OutputStream& operator<<( const ObjectGLenum& value ); - OutputStream& operator<<( const ObjectProperty& prop ); - OutputStream& operator<<( const ObjectMark& mark ); - // Convenient methods for writing inline void writeWrappedString( const std::string& str ); - inline void writeCharArray( const char* s, unsigned int size ); + void writeCharArray( const char* s, unsigned int size ) { _out->writeCharArray(s, size); } // Global writing functions void writeArray( const osg::Array* a ); @@ -140,7 +134,7 @@ public: void writeImage( const osg::Image* img ); void writeObject( const osg::Object* obj ); - void start( WriteType type ); + void start( OutputIterator* outIterator, WriteType type ); void compress( std::ostream* ostream ); // Schema handlers @@ -156,200 +150,13 @@ protected: ArrayMap _arrayMap; ObjectMap _objectMap; - WriteMode _writeMode; WriteImageHint _writeImageHint; - - bool _readyForEndBracket; - int _indent; std::string _currentField; std::string _compressorName; std::stringstream _compressSource; - std::ostream* _out; + OutputIterator* _out; }; -// INLINE METHODS - -OutputStream& OutputStream::operator<<( bool b ) -{ - if ( isBinary() ) - { - char c = b?1:0; - _out->write( &c, CHAR_SIZE ); - } - else - { - if ( b ) *_out << "TRUE "; - else *_out << "FALSE "; - } - return *this; -} - -OutputStream& OutputStream::operator<<( char c ) -{ - if ( isBinary() ) - { - _out->write( &c, CHAR_SIZE ); - } - else - { - *_out << (short)c << ' '; - } - return *this; -} - -OutputStream& OutputStream::operator<<( unsigned char c ) -{ - if ( isBinary() ) - { - _out->write( (char*)&c, CHAR_SIZE ); - } - else - { - *_out << (unsigned short)c << ' '; - } - return *this; -} - -OutputStream& OutputStream::operator<<( short s ) -{ - if ( isBinary() ) - { - _out->write( (char*)&s, SHORT_SIZE ); - } - else - { - *_out << s << ' '; - } - return *this; -} - -OutputStream& OutputStream::operator<<( unsigned short s ) -{ - if ( isBinary() ) - { - _out->write( (char*)&s, SHORT_SIZE ); - } - else - { - *_out << s << ' '; - } - return *this; -} - -OutputStream& OutputStream::operator<<( int i ) -{ - if ( isBinary() ) - { - _out->write( (char*)&i, INT_SIZE ); - } - else - { - *_out << i << ' '; - } - return *this; -} - -OutputStream& OutputStream::operator<<( unsigned int i ) -{ - if ( isBinary() ) - { - _out->write( (char*)&i, INT_SIZE ); - } - else - { - *_out << i << ' '; - } - return *this; -} - -OutputStream& OutputStream::operator<<( long l ) -{ - if ( isBinary() ) - { - _out->write( (char*)&l, LONG_SIZE ); - } - else - { - *_out << l << ' '; - } - return *this; -} - -OutputStream& OutputStream::operator<<( unsigned long l ) -{ - if ( isBinary() ) - { - _out->write( (char*)&l, LONG_SIZE ); - } - else - { - *_out << l << ' '; - } - return *this; -} - -OutputStream& OutputStream::operator<<( float f ) -{ - if ( isBinary() ) - { - _out->write( (char*)&f, FLOAT_SIZE ); - } - else - { - *_out << f << ' '; - } - return *this; -} - -OutputStream& OutputStream::operator<<( double d ) -{ - if ( isBinary() ) - { - _out->write((char*)&d, DOUBLE_SIZE); - } - else - { - *_out << d << ' '; - } - return *this; -} - -OutputStream& OutputStream::operator<<( const std::string& s ) -{ - if ( isBinary() ) - { - int size = s.size(); - _out->write( (char*)&size, INT_SIZE ); - _out->write( s.c_str(), s.size() ); - } - else - { - *_out << s << ' '; - } - return *this; -} - -OutputStream& OutputStream::operator<<( std::ostream& (*fn)(std::ostream&) ) -{ - if ( !isBinary() ) - { - *_out << fn; - if ( fn==static_cast(std::endl) ) - { - _readyForEndBracket = true; - for (int i=0; i<_indent; ++i) - *_out << ' '; - } - } - return *this; -} - -OutputStream& OutputStream::operator<<( std::ios_base& (*fn)(std::ios_base&) ) -{ - if ( !isBinary() ) *_out << fn; - return *this; -} - void OutputStream::writeWrappedString( const std::string& str ) { if ( !isBinary() ) @@ -361,21 +168,6 @@ void OutputStream::writeWrappedString( const std::string& str ) *this << str; } -void OutputStream::writeCharArray( const char* s, unsigned int size ) -{ - if ( size>0 ) - { - if ( isBinary() ) - { - _out->write( s, size ); - } - else - { - *_out << s << ' '; - } - } -} - } #endif diff --git a/include/osgDB/Serializer b/include/osgDB/Serializer index e36972545..09570d7ef 100644 --- a/include/osgDB/Serializer +++ b/include/osgDB/Serializer @@ -12,8 +12,8 @@ */ // Written by Wang Rui, (C) 2010 -#ifndef H_SERIALIZER -#define H_SERIALIZER +#ifndef OSGDB__SERIALIZER +#define OSGDB__SERIALIZER #include #include diff --git a/include/osgDB/StreamOperator b/include/osgDB/StreamOperator new file mode 100755 index 000000000..9498499fe --- /dev/null +++ b/include/osgDB/StreamOperator @@ -0,0 +1,91 @@ +#ifndef OSGDB_STREAMOPERATOR +#define OSGDB_STREAMOPERATOR + +#include +#include +#include + +namespace osgDB +{ + +class OSGDB_EXPORT OutputIterator +{ +public: + OutputIterator() : _out(0) {} + virtual ~OutputIterator() {} + + void setStream( std::ostream* ostream ) { _out = ostream; } + std::ostream* getStream() { return _out; } + const std::ostream* getStream() const { return _out; } + + virtual bool isBinary() const = 0; + + virtual void writeBool( bool b ) = 0; + virtual void writeChar( char c ) = 0; + virtual void writeUChar( unsigned char c ) = 0; + virtual void writeShort( short s ) = 0; + virtual void writeUShort( unsigned short s ) = 0; + virtual void writeInt( int i ) = 0; + virtual void writeUInt( unsigned int i ) = 0; + virtual void writeLong( long l ) = 0; + virtual void writeULong( unsigned long l ) = 0; + virtual void writeFloat( float f ) = 0; + virtual void writeDouble( double d ) = 0; + virtual void writeString( const std::string& s ) = 0; + virtual void writeStream( std::ostream& (*fn)(std::ostream&) ) = 0; + virtual void writeBase( std::ios_base& (*fn)(std::ios_base&) ) = 0; + + virtual void writeGLenum( const ObjectGLenum& value ) = 0; + virtual void writeProperty( const ObjectProperty& prop ) = 0; + virtual void writeMark( const ObjectMark& mark ) = 0; + virtual void writeCharArray( const char* s, unsigned int size ) = 0; + +protected: + std::ostream* _out; +}; + +class OSGDB_EXPORT InputIterator +{ +public: + InputIterator() : _in(0), _failed(false) {} + virtual ~InputIterator() {} + + void setStream( std::istream* istream ) { _in = istream; } + std::istream* getStream() { return _in; } + const std::istream* getStream() const { return _in; } + + bool isFailed() const { return _failed; } + virtual bool isBinary() const = 0; + + virtual void readBool( bool& b ) = 0; + virtual void readChar( char& c ) = 0; + virtual void readSChar( signed char& c ) = 0; + virtual void readUChar( unsigned char& c ) = 0; + virtual void readShort( short& s ) = 0; + virtual void readUShort( unsigned short& s ) = 0; + virtual void readInt( int& i ) = 0; + virtual void readUInt( unsigned int& i ) = 0; + virtual void readLong( long& l ) = 0; + virtual void readULong( unsigned long& l ) = 0; + virtual void readFloat( float& f ) = 0; + virtual void readDouble( double& d ) = 0; + virtual void readString( std::string& s ) = 0; + virtual void readStream( std::istream& (*fn)(std::istream&) ) = 0; + virtual void readBase( std::ios_base& (*fn)(std::ios_base&) ) = 0; + + virtual void readGLenum( ObjectGLenum& value ) = 0; + virtual void readProperty( ObjectProperty& prop ) = 0; + virtual void readMark( ObjectMark& mark ) = 0; + virtual void readCharArray( char* s, unsigned int size ) = 0; + +protected: + void checkStream() const + { if (_in->rdstate()&_in->failbit) _failed = true; } + + std::istream* _in; + mutable bool _failed; +}; + +} + +#endif diff --git a/src/osgDB/CMakeLists.txt b/src/osgDB/CMakeLists.txt index 6963d7969..2968ae658 100644 --- a/src/osgDB/CMakeLists.txt +++ b/src/osgDB/CMakeLists.txt @@ -20,6 +20,7 @@ SET(LIB_NAME osgDB) SET(HEADER_PATH ${OpenSceneGraph_SOURCE_DIR}/include/${LIB_NAME}) SET(LIB_PUBLIC_HEADERS ${HEADER_PATH}/DataTypes + ${HEADER_PATH}/StreamOperator ${HEADER_PATH}/Serializer ${HEADER_PATH}/ObjectWrapper ${HEADER_PATH}/InputStream diff --git a/src/osgDB/InputStream.cpp b/src/osgDB/InputStream.cpp index 789c5107e..330681bd4 100644 --- a/src/osgDB/InputStream.cpp +++ b/src/osgDB/InputStream.cpp @@ -23,12 +23,10 @@ using namespace osgDB; static std::string s_lastSchema; -InputStream::InputStream( std::istream* istream, const osgDB::Options* options ) -: _readMode(READ_BINARY), _byteSwap(0), _useFloatMatrix(false), - _in(istream) +InputStream::InputStream( const osgDB::Options* options ) +: _byteSwap(0), _useFloatMatrix(false), + _in(0) { - if ( !_in ) - throw InputException(_currentField, "InputStream: Null stream specified."); if ( !options ) return; std::string schema; @@ -38,7 +36,9 @@ InputStream::InputStream( std::istream* istream, const osgDB::Options* options ) { const std::string& option = *itr; if ( option=="Ascii" ) - _readMode = READ_ASCII; + { + // Omit this + } else { StringList keyAndValues; @@ -157,68 +157,6 @@ InputStream& InputStream::operator>>( osg::Matrixd& mat ) return *this; } -InputStream& InputStream::operator>>( ObjectGLenum& value ) -{ - GLenum e = 0; - if ( isBinary() ) - { - _in->read( (char*)&e, GLENUM_SIZE ); checkStream(); - if ( _byteSwap ) osg::swapBytes( (char*)&e, GLENUM_SIZE ); - } - else - { - std::string enumString; - *this >> enumString; - e = osgDB::Registry::instance()->getObjectWrapperManager()->getValue("GL", enumString); - } - value.set( e ); - return *this; -} - -InputStream& InputStream::operator>>( ObjectProperty& prop ) -{ - int value = 0; - if ( isBinary() ) - { - if ( prop._mapProperty ) - { - _in->read( (char*)&value, INT_SIZE ); checkStream(); - if ( _byteSwap ) osg::swapBytes( (char*)&value, INT_SIZE ); - } - } - else - { - std::string enumString; - *this >> enumString; - if ( prop._mapProperty ) - { - value = osgDB::Registry::instance()->getObjectWrapperManager()->getValue(prop._name, enumString); - } - else - { - if ( prop._name!=enumString ) - { - osg::notify(osg::WARN) << "InputStream::operator>>(ObjectProperty&): Unmatched property " - << enumString << ", expecting " << prop._name - << ". At " << _currentField << std::endl; - } - prop._name = enumString; - } - } - prop.set( value ); - return *this; -} - -InputStream& InputStream::operator>>( ObjectMark& mark ) -{ - if ( !isBinary() ) - { - std::string markString; - *this >> markString; - } - return *this; -} - osg::Array* InputStream::readArray() { osg::ref_ptr array = NULL; @@ -635,32 +573,25 @@ void InputStream::readSchema( std::istream& fin ) } } -InputStream::ReadType InputStream::start() +InputStream::ReadType InputStream::start( InputIterator* inIterator ) { ReadType type = READ_UNKNOWN; _currentField = "Header"; + _in = inIterator; + if ( !_in ) + throw InputException(_currentField, "InputStream: Null stream specified."); // Check OSG header information unsigned int version = 0; if ( isBinary() ) { - unsigned int headerLow = 0, headerHigh = 0; - *this >> headerLow >> headerHigh; - if ( headerLow!=OSG_HEADER_LOW || headerHigh!=OSG_HEADER_HIGH ) - { - _in->seekg( 0, std::ios::beg ); - _readMode = READ_ASCII; - } - else - { - unsigned int typeValue; - *this >> typeValue >> version; - type = static_cast(typeValue); - - unsigned int matrixValueType; *this >> matrixValueType; - if ( matrixValueType==0 ) _useFloatMatrix = true; - else _useFloatMatrix = false; - } + unsigned int typeValue; + *this >> typeValue >> version; + type = static_cast(typeValue); + + unsigned int matrixValueType; *this >> matrixValueType; + if ( matrixValueType==0 ) _useFloatMatrix = true; + else _useFloatMatrix = false; } if ( !isBinary() ) { @@ -702,9 +633,9 @@ void InputStream::decompress() } std::string data; - if ( !compressor->decompress(*_in, data) ) + if ( !compressor->decompress(*(_in->getStream()), data) ) throw InputException(_currentField, "InputStream: Failed to decompress stream."); - _in = new std::stringstream(data); + _in->setStream( new std::stringstream(data) ); } // PROTECTED METHODS @@ -745,7 +676,7 @@ void InputStream::readArrayImplementation( T* a, int readSize, bool useByteSwap a->resize( size ); if ( isBinary() ) { - _in->read( (char*)&((*a)[0]), readSize*size ); checkStream(); + _in->getStream()->read( (char*)&((*a)[0]), readSize*size ); checkStream(); if ( useByteSwap && _byteSwap ) { for ( int i=0; iwrite((char*)&e, GLENUM_SIZE); - } - else - { - const std::string& enumString = osgDB::Registry::instance()->getObjectWrapperManager()->getString("GL", e); - *_out << enumString << ' '; - } - return *this; -} - -OutputStream& OutputStream::operator<<( const ObjectProperty& prop ) -{ - if ( isBinary() ) - { - if ( prop._mapProperty ) - _out->write( (char*)&(prop._value), INT_SIZE ); - } - else - { - std::string enumString = prop._name; - if ( prop._mapProperty ) - { - enumString = osgDB::Registry::instance()->getObjectWrapperManager()->getString(prop._name, prop._value); - } - *_out << enumString << ' '; - } - return *this; -} - -OutputStream& OutputStream::operator<<( const ObjectMark& mark ) -{ - if ( !isBinary() ) - { - int delta = mark._indentDelta; - if ( delta<0 && _readyForEndBracket ) - { - if ( _indent<-delta ) delta = -_indent; - _readyForEndBracket = false; - _out->seekp( delta, std::ios::cur ); - } - _indent += delta; - *this << mark._name; - } - return *this; -} - void OutputStream::writeArray( const osg::Array* a ) { if ( !a ) return; @@ -485,9 +433,12 @@ void OutputStream::writeObject( const osg::Object* obj ) *this << END_BRACKET << std::endl; } -void OutputStream::start( OutputStream::WriteType type ) +void OutputStream::start( OutputIterator* outIterator, OutputStream::WriteType type ) { _currentField = "Header"; + _out = outIterator; + if ( !_out ) + throw OutputException(_currentField, "OutputStream: Null stream specified."); if ( isBinary() ) { @@ -508,8 +459,8 @@ void OutputStream::start( OutputStream::WriteType type ) else { *this << _compressorName; - _out->flush(); - _out = &_compressSource; + _out->getStream()->flush(); + _out->setStream( &_compressSource ); return; } } diff --git a/src/osgPlugins/osg/AsciiStreamOperator.h b/src/osgPlugins/osg/AsciiStreamOperator.h new file mode 100644 index 000000000..4dc70ff96 --- /dev/null +++ b/src/osgPlugins/osg/AsciiStreamOperator.h @@ -0,0 +1,217 @@ +#ifndef OSGDB_ASCIISTREAMOPERATOR +#define OSGDB_ASCIISTREAMOPERATOR + +#include + +class AsciiOutputIterator : public osgDB::OutputIterator +{ +public: + AsciiOutputIterator( std::ostream* ostream ) + : _readyForEndBracket(false), _indent(0) { _out = ostream; } + + virtual ~AsciiOutputIterator() {} + + virtual bool isBinary() const { return false; } + + virtual void writeBool( bool b ) + { + if ( b ) *_out << "TRUE "; + else *_out << "FALSE "; + } + + virtual void writeChar( char c ) + { *_out << (short)c << ' '; } + + virtual void writeUChar( unsigned char c ) + { *_out << (unsigned short)c << ' '; } + + virtual void writeShort( short s ) + { *_out << s << ' '; } + + virtual void writeUShort( unsigned short s ) + { *_out << s << ' '; } + + virtual void writeInt( int i ) + { *_out << i << ' '; } + + virtual void writeUInt( unsigned int i ) + { *_out << i << ' '; } + + virtual void writeLong( long l ) + { *_out << l << ' '; } + + virtual void writeULong( unsigned long l ) + { *_out << l << ' '; } + + virtual void writeFloat( float f ) + { *_out << f << ' '; } + + virtual void writeDouble( double d ) + { *_out << d << ' '; } + + virtual void writeString( const std::string& s ) + { *_out << s << ' '; } + + virtual void writeStream( std::ostream& (*fn)(std::ostream&) ) + { + *_out << fn; + if ( fn==static_cast(std::endl) ) + { + _readyForEndBracket = true; + for (int i=0; i<_indent; ++i) + *_out << ' '; + } + } + + virtual void writeBase( std::ios_base& (*fn)(std::ios_base&) ) + { + *_out << fn; + } + + virtual void writeGLenum( const osgDB::ObjectGLenum& value ) + { + GLenum e = value.get(); + const std::string& enumString = osgDB::Registry::instance()->getObjectWrapperManager()->getString("GL", e); + *_out << enumString << ' '; + } + + virtual void writeProperty( const osgDB::ObjectProperty& prop ) + { + std::string enumString = prop._name; + if ( prop._mapProperty ) + { + enumString = osgDB::Registry::instance()->getObjectWrapperManager()->getString(prop._name, prop._value); + } + *_out << enumString << ' '; + } + + virtual void writeMark( const osgDB::ObjectMark& mark ) + { + int delta = mark._indentDelta; + if ( delta<0 && _readyForEndBracket ) + { + if ( _indent<-delta ) delta = -_indent; + _readyForEndBracket = false; + _out->seekp( delta, std::ios::cur ); + } + _indent += delta; + *_out << mark._name << ' '; + } + + virtual void writeCharArray( const char* s, unsigned int size ) {} + +protected: + bool _readyForEndBracket; + int _indent; +}; + +class AsciiInputIterator : public osgDB::InputIterator +{ +public: + AsciiInputIterator( std::istream* istream ) { _in = istream; } + virtual ~AsciiInputIterator() {} + + virtual bool isBinary() const { return false; } + + virtual void readBool( bool& b ) + { + std::string boolString; + *_in >> boolString; checkStream(); + if ( boolString=="TRUE" ) b = true; + else b = false; + } + + virtual void readChar( char& c ) + { + short s = 0; + *_in >> s; checkStream(); + c = (char)s; + } + + virtual void readSChar( signed char& c ) + { + short s = 0; + *_in >> s; checkStream(); + c = (signed char)s; + } + + virtual void readUChar( unsigned char& c ) + { + short s = 0; + *_in >> s; checkStream(); + c = (unsigned char)s; + } + + virtual void readShort( short& s ) + { *_in >> s; checkStream(); } + + virtual void readUShort( unsigned short& s ) + { *_in >> s; checkStream(); } + + virtual void readInt( int& i ) + { *_in >> i; checkStream(); } + + virtual void readUInt( unsigned int& i ) + { *_in >> i; checkStream(); } + + virtual void readLong( long& l ) + { *_in >> l; checkStream(); } + + virtual void readULong( unsigned long& l ) + { *_in >> l; checkStream(); } + + virtual void readFloat( float& f ) + { *_in >> f; checkStream(); } + + virtual void readDouble( double& d ) + { *_in >> d; checkStream(); } + + virtual void readString( std::string& s ) + { *_in >> s; checkStream(); } + + virtual void readStream( std::istream& (*fn)(std::istream&) ) + { *_in >> fn; } + + virtual void readBase( std::ios_base& (*fn)(std::ios_base&) ) + { *_in >> fn; } + + virtual void readGLenum( osgDB::ObjectGLenum& value ) + { + GLenum e = 0; + std::string enumString; + *_in >> enumString; checkStream(); + e = osgDB::Registry::instance()->getObjectWrapperManager()->getValue("GL", enumString); + value.set( e ); + } + + virtual void readProperty( osgDB::ObjectProperty& prop ) + { + int value = 0; + std::string enumString; + *_in >> enumString; checkStream(); + if ( prop._mapProperty ) + { + value = osgDB::Registry::instance()->getObjectWrapperManager()->getValue(prop._name, enumString); + } + else + { + if ( prop._name!=enumString ) + { + osg::notify(osg::WARN) << "AsciiInputIterator::readProperty(): Unmatched property " + << enumString << ", expecting " << prop._name << std::endl; + } + prop._name = enumString; + } + prop.set( value ); + } + + virtual void readMark( osgDB::ObjectMark& mark ) + { + std::string markString; + *_in >> markString; checkStream(); + } + + virtual void readCharArray( char* s, unsigned int size ) {} +}; + +#endif diff --git a/src/osgPlugins/osg/BinaryStreamOperator.h b/src/osgPlugins/osg/BinaryStreamOperator.h new file mode 100644 index 000000000..c5176c2b0 --- /dev/null +++ b/src/osgPlugins/osg/BinaryStreamOperator.h @@ -0,0 +1,184 @@ +#ifndef OSG2_BINARYSTREAMOPERATOR +#define OSG2_BINARYSTREAMOPERATOR + +#include + +class BinaryOutputIterator : public osgDB::OutputIterator +{ +public: + BinaryOutputIterator( std::ostream* ostream ) { _out = ostream; } + virtual ~BinaryOutputIterator() {} + + virtual bool isBinary() const { return true; } + + virtual void writeBool( bool b ) + { char c = b?1:0; _out->write( &c, CHAR_SIZE ); } + + virtual void writeChar( char c ) + { _out->write( &c, CHAR_SIZE ); } + + virtual void writeUChar( unsigned char c ) + { _out->write( (char*)&c, CHAR_SIZE ); } + + virtual void writeShort( short s ) + { _out->write( (char*)&s, SHORT_SIZE ); } + + virtual void writeUShort( unsigned short s ) + { _out->write( (char*)&s, SHORT_SIZE ); } + + virtual void writeInt( int i ) + { _out->write( (char*)&i, INT_SIZE ); } + + virtual void writeUInt( unsigned int i ) + { _out->write( (char*)&i, INT_SIZE ); } + + virtual void writeLong( long l ) + { _out->write( (char*)&l, LONG_SIZE ); } + + virtual void writeULong( unsigned long l ) + { _out->write( (char*)&l, LONG_SIZE ); } + + virtual void writeFloat( float f ) + { _out->write( (char*)&f, FLOAT_SIZE ); } + + virtual void writeDouble( double d ) + { _out->write((char*)&d, DOUBLE_SIZE); } + + virtual void writeString( const std::string& s ) + { + int size = s.size(); + _out->write( (char*)&size, INT_SIZE ); + _out->write( s.c_str(), s.size() ); + } + + virtual void writeStream( std::ostream& (*fn)(std::ostream&) ) {} + + virtual void writeBase( std::ios_base& (*fn)(std::ios_base&) ) {} + + virtual void writeGLenum( const osgDB::ObjectGLenum& value ) + { GLenum e = value.get(); _out->write((char*)&e, GLENUM_SIZE); } + + virtual void writeProperty( const osgDB::ObjectProperty& prop ) + { if (prop._mapProperty) _out->write((char*)&(prop._value), INT_SIZE); } + + virtual void writeMark( const osgDB::ObjectMark& mark ) {} + + virtual void writeCharArray( const char* s, unsigned int size ) + { if ( size>0 ) _out->write( s, size ); } +}; + +class BinaryInputIterator : public osgDB::InputIterator +{ +public: + BinaryInputIterator( std::istream* istream ) : _byteSwap(0) { _in = istream; } + virtual ~BinaryInputIterator() {} + + virtual bool isBinary() const { return true; } + + virtual void readBool( bool& b ) + { + char c = 0; + _in->read( &c, CHAR_SIZE ); checkStream(); + b = (c!=0); + } + + virtual void readChar( char& c ) + { _in->read( &c, CHAR_SIZE ); checkStream(); } + + virtual void readSChar( signed char& c ) + { _in->read( (char*)&c, CHAR_SIZE ); checkStream(); } + + virtual void readUChar( unsigned char& c ) + { _in->read( (char*)&c, CHAR_SIZE ); checkStream(); } + + virtual void readShort( short& s ) + { + _in->read( (char*)&s, SHORT_SIZE ); checkStream(); + if ( _byteSwap ) osg::swapBytes( (char*)&s, SHORT_SIZE ); + } + + virtual void readUShort( unsigned short& s ) + { + _in->read( (char*)&s, SHORT_SIZE ); checkStream(); + if ( _byteSwap ) osg::swapBytes( (char*)&s, SHORT_SIZE ); + } + + virtual void readInt( int& i ) + { + _in->read( (char*)&i, INT_SIZE ); checkStream(); + if ( _byteSwap ) osg::swapBytes( (char*)&i, INT_SIZE ); + } + + virtual void readUInt( unsigned int& i ) + { + _in->read( (char*)&i, INT_SIZE ); checkStream(); + if ( _byteSwap ) osg::swapBytes( (char*)&i, INT_SIZE ); + } + + virtual void readLong( long& l ) + { + _in->read( (char*)&l, LONG_SIZE ); checkStream(); + if ( _byteSwap ) osg::swapBytes( (char*)&l, LONG_SIZE ); + } + + virtual void readULong( unsigned long& l ) + { + _in->read( (char*)&l, LONG_SIZE ); checkStream(); + if ( _byteSwap ) osg::swapBytes( (char*)&l, LONG_SIZE ); + } + + virtual void readFloat( float& f ) + { + _in->read( (char*)&f, FLOAT_SIZE ); checkStream(); + if ( _byteSwap ) osg::swapBytes( (char*)&f, FLOAT_SIZE ); + } + + virtual void readDouble( double& d ) + { + _in->read( (char*)&d, DOUBLE_SIZE ); checkStream(); + if ( _byteSwap ) osg::swapBytes( (char*)&d, DOUBLE_SIZE ); + } + + virtual void readString( std::string& s ) + { + int size = 0; readInt( size ); + if ( size ) + { + s.resize( size ); + _in->read( (char*)s.c_str(), size ); checkStream(); + } + } + + virtual void readStream( std::istream& (*fn)(std::istream&) ) {} + + virtual void readBase( std::ios_base& (*fn)(std::ios_base&) ) {} + + virtual void readGLenum( osgDB::ObjectGLenum& value ) + { + GLenum e = 0; + _in->read( (char*)&e, GLENUM_SIZE ); checkStream(); + if ( _byteSwap ) osg::swapBytes( (char*)&e, GLENUM_SIZE ); + value.set( e ); + } + + virtual void readProperty( osgDB::ObjectProperty& prop ) + { + int value = 0; + if ( prop._mapProperty ) + { + _in->read( (char*)&value, INT_SIZE ); checkStream(); + if ( _byteSwap ) osg::swapBytes( (char*)&value, INT_SIZE ); + } + prop.set( value ); + } + + virtual void readMark( osgDB::ObjectMark& mark ) {} + + virtual void readCharArray( char* s, unsigned int size ) + { if ( size>0 ) _in->read( s, size ); checkStream(); } + +protected: + int _byteSwap; +}; + +#endif diff --git a/src/osgPlugins/osg/ReaderWriterOSG2.cpp b/src/osgPlugins/osg/ReaderWriterOSG2.cpp index dff4d5be9..02e949512 100644 --- a/src/osgPlugins/osg/ReaderWriterOSG2.cpp +++ b/src/osgPlugins/osg/ReaderWriterOSG2.cpp @@ -16,9 +16,24 @@ #include #include #include +#include "AsciiStreamOperator.h" +#include "BinaryStreamOperator.h" using namespace osgDB; +bool checkBinary( std::istream* fin ) +{ + unsigned int headerLow = 0, headerHigh = 0; + fin->read( (char*)&headerLow, INT_SIZE ); + fin->read( (char*)&headerHigh, INT_SIZE ); + if ( headerLow!=OSG_HEADER_LOW || headerHigh!=OSG_HEADER_HIGH ) + { + fin->seekg( 0, std::ios::beg ); + return false; + } + return true; +} + class ReaderWriterOSG2 : public osgDB::ReaderWriter { public: @@ -76,8 +91,15 @@ public: { try { - InputStream is( &fin, options ); - if ( is.start()!=InputStream::READ_IMAGE ) + InputStream is( options ); + + InputIterator* ii = NULL; + if ( !checkBinary(&fin) ) + ii = new AsciiInputIterator(&fin); + else + ii = new BinaryInputIterator(&fin); + + if ( is.start(ii)!=InputStream::READ_IMAGE ) return ReadResult::FILE_NOT_HANDLED; is.decompress(); return is.readImage(); @@ -107,8 +129,15 @@ public: { try { - InputStream is( &fin, options ); - if ( is.start()!=InputStream::READ_SCENE ) + InputStream is( options ); + + InputIterator* ii = NULL; + if ( !checkBinary(&fin) ) + ii = new AsciiInputIterator(&fin); + else + ii = new BinaryInputIterator(&fin); + + if ( is.start(ii)!=InputStream::READ_SCENE ) return ReadResult::FILE_NOT_HANDLED; is.decompress(); return dynamic_cast( is.readObject() ); @@ -162,8 +191,15 @@ public: { try { - OutputStream os( &fout, options ); - os.start( OutputStream::WRITE_IMAGE ); + OutputStream os( options ); + + osgDB::OutputIterator* oi = NULL; + if ( options && options->getOptionString().find("Ascii")!=std::string::npos ) + oi = new AsciiOutputIterator(&fout); + else + oi = new BinaryOutputIterator(&fout); + + os.start( oi, OutputStream::WRITE_IMAGE ); os.writeImage( &image ); os.compress( &fout ); @@ -201,8 +237,15 @@ public: { try { - OutputStream os( &fout, options ); - os.start( OutputStream::WRITE_SCENE ); + OutputStream os( options ); + + osgDB::OutputIterator* oi = NULL; + if ( options && options->getOptionString().find("Ascii")!=std::string::npos ) + oi = new AsciiOutputIterator(&fout); + else + oi = new BinaryOutputIterator(&fout); + + os.start( oi, OutputStream::WRITE_SCENE ); os.writeObject( &node ); os.compress( &fout );