From Wang Rui, refactored the InputStream/OutputStream operations so that the binar/ascii foramts are implemented via subclasses.

This commit is contained in:
Robert Osfield 2010-01-25 11:03:21 +00:00
parent f8fc4f66a8
commit a520e8b6bd
12 changed files with 647 additions and 660 deletions

View File

@ -12,8 +12,8 @@
*/
// Written by Wang Rui, (C) 2010
#ifndef H_DATATYPES
#define H_DATATYPES
#ifndef OSGDB_DATATYPES
#define OSGDB_DATATYPES
#include <string>
@ -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;

View File

@ -12,8 +12,8 @@
*/
// Written by Wang Rui, (C) 2010
#ifndef H_INPUTSTREAM
#define H_INPUTSTREAM
#ifndef OSGDB_INPUTSTREAM
#define OSGDB_INPUTSTREAM
#include <osg/Endian>
#include <osg/Vec2>
@ -24,7 +24,7 @@
#include <osg/Array>
#include <osg/PrimitiveSet>
#include <osgDB/ReaderWriter>
#include <osgDB/DataTypes>
#include <osgDB/StreamOperator>
#include <iostream>
#include <sstream>
@ -51,12 +51,6 @@ public:
typedef std::map< unsigned int, osg::ref_ptr<osg::Array> > ArrayMap;
typedef std::map< unsigned int, osg::ref_ptr<osg::Object> > 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<typename T> InputStream& operator>>( osg::ref_ptr<T>& ptr )
{ ptr = static_cast<T*>(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.");
}

View File

@ -12,8 +12,8 @@
*/
// Written by Wang Rui, (C) 2010
#ifndef H_OBJECTWRAPPER
#define H_OBJECTWRAPPER
#ifndef OSGDB_OBJECTWRAPPER
#define OSGDB_OBJECTWRAPPER
#include <osgDB/Serializer>

View File

@ -12,8 +12,8 @@
*/
// Written by Wang Rui, (C) 2010
#ifndef H_OUTPUTSTREAM
#define H_OUTPUTSTREAM
#ifndef OSGDB_OUTPUTSTREAM
#define OSGDB_OUTPUTSTREAM
#include <osg/Vec2>
#include <osg/Vec3>
@ -23,7 +23,7 @@
#include <osg/Array>
#include <osg/PrimitiveSet>
#include <osgDB/ReaderWriter>
#include <osgDB/DataTypes>
#include <osgDB/StreamOperator>
#include <iostream>
#include <sstream>
@ -50,12 +50,6 @@ public:
typedef std::map<const osg::Array*, unsigned int> ArrayMap;
typedef std::map<const osg::Object*, unsigned int> 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<typename T> OutputStream& operator<<( const osg::ref_ptr<T>& 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::ostream& (*)(std::ostream&)>(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

View File

@ -12,8 +12,8 @@
*/
// Written by Wang Rui, (C) 2010
#ifndef H_SERIALIZER
#define H_SERIALIZER
#ifndef OSGDB__SERIALIZER
#define OSGDB__SERIALIZER
#include <osg/ref_ptr>
#include <osg/Notify>

91
include/osgDB/StreamOperator Executable file
View File

@ -0,0 +1,91 @@
#ifndef OSGDB_STREAMOPERATOR
#define OSGDB_STREAMOPERATOR
#include <iostream>
#include <sstream>
#include <osgDB/DataTypes>
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

View File

@ -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

View File

@ -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<osg::Array> 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<ReadType>(typeValue);
unsigned int matrixValueType; *this >> matrixValueType;
if ( matrixValueType==0 ) _useFloatMatrix = true;
else _useFloatMatrix = false;
}
unsigned int typeValue;
*this >> typeValue >> version;
type = static_cast<ReadType>(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; i<size; ++i )

View File

@ -21,13 +21,10 @@
using namespace osgDB;
OutputStream::OutputStream( std::ostream* ostream, const osgDB::Options* options )
: _writeMode(WRITE_BINARY), _writeImageHint(WRITE_USE_IMAGE_HINT),
_readyForEndBracket(false), _indent(0),
_out(ostream)
OutputStream::OutputStream( const osgDB::Options* options )
: _writeImageHint(WRITE_USE_IMAGE_HINT),
_out(0)
{
if ( !_out )
throw OutputException(_currentField, "OutputStream: Null stream specified.");
if ( !options ) return;
StringList optionList;
@ -36,7 +33,9 @@ OutputStream::OutputStream( std::ostream* ostream, const osgDB::Options* options
{
const std::string& option = *itr;
if ( option=="Ascii" )
_writeMode = WRITE_ASCII;
{
// Omit this
}
else
{
StringList keyAndValues;
@ -137,57 +136,6 @@ OutputStream& OutputStream::operator<<( const osg::Matrixd& mat )
return *this;
}
OutputStream& OutputStream::operator<<( const ObjectGLenum& value )
{
GLenum e = value.get();
if ( isBinary() )
{
_out->write((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;
}
}

View File

@ -0,0 +1,217 @@
#ifndef OSGDB_ASCIISTREAMOPERATOR
#define OSGDB_ASCIISTREAMOPERATOR
#include <osgDB/StreamOperator>
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::ostream& (*)(std::ostream&)>(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

View File

@ -0,0 +1,184 @@
#ifndef OSG2_BINARYSTREAMOPERATOR
#define OSG2_BINARYSTREAMOPERATOR
#include <osgDB/StreamOperator>
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

View File

@ -16,9 +16,24 @@
#include <osgDB/FileUtils>
#include <osgDB/Registry>
#include <osgDB/ObjectWrapper>
#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<osg::Node*>( 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 );