Hi Robert, Here a fix about a leak in InputStream::decompress
I changed
_in->setStream( new std::stringstream(data) );
to
_dataDecompress = new std::stringstream(data);
_in->setStream( _dataDecompress );
Then when the destructor is of InputStream is called I delete the
dataDecompress stringstream.
Cheers,
Cedric
--
Provide OpenGL, WebGL and OpenSceneGraph services
+33 659 598 614 Cedric Pinson mailto:[email protected]
http://www.plopbyte.net
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
// Written by Wang Rui, (C) 2010
#include <osg/Notify>
#include <osg/ImageSequence>
#include <osgDB/ReadFile>
#include <osgDB/XmlParser>
#include <osgDB/FileNameUtils>
#include <osgDB/ObjectWrapper>
using namespace osgDB;
static std::string s_lastSchema;
InputStream::InputStream( const osgDB::Options* options )
: _byteSwap(0), _useFloatMatrix(true), _useSchemaData(false), _forceReadingImage(false), _dataDecompress(0)
{
if ( !options ) return;
_options = options;
std::string schema;
StringList optionList;
split( options->getOptionString(), optionList );
for ( StringList::iterator itr=optionList.begin(); itr!=optionList.end(); ++itr )
{
const std::string& option = *itr;
if ( option=="Ascii" )
{
// Omit this
}
else if ( option=="ForceReadingImage" )
{
_forceReadingImage = true;
}
else
{
StringList keyAndValues;
split( option, keyAndValues, '=' );
if ( keyAndValues.size()<2 ) continue;
if ( keyAndValues[0]=="SchemaFile" )
{
schema = keyAndValues[1];
if ( s_lastSchema!=schema )
{
osgDB::ifstream schemaStream( schema.c_str(), std::ios::in );
if ( !schemaStream.fail() ) readSchema( schemaStream );
schemaStream.close();
s_lastSchema = schema;
}
}
else
OSG_WARN << "InputStream: Unknown option " << option << std::endl;
}
}
if ( schema.empty() )
{
resetSchema();
s_lastSchema.clear();
}
}
InputStream::~InputStream()
{
if (_dataDecompress)
delete _dataDecompress;
}
InputStream& InputStream::operator>>( osg::Vec2b& v )
{
char x, y; *this >> x >> y;
v.set( x, y );
return *this;
}
InputStream& InputStream::operator>>( osg::Vec3b& v )
{
char x, y, z; *this >> x >> y >> z;
v.set( x, y, z );
return *this;
}
InputStream& InputStream::operator>>( osg::Vec4b& v )
{
char x, y, z, w; *this >> x >> y >> z >> w;
v.set( x, y, z, w );
return *this;
}
InputStream& InputStream::operator>>( osg::Vec4ub& v )
{
char r, g, b, a; *this >> r >> g >> b >> a;
v.set( r, g, b, a );
return *this;
}
InputStream& InputStream::operator>>( osg::Vec2s& v )
{ *this >> v.x() >> v.y(); return *this; }
InputStream& InputStream::operator>>( osg::Vec3s& v )
{ *this >> v.x() >> v.y() >> v.z(); return *this; }
InputStream& InputStream::operator>>( osg::Vec4s& v )
{ *this >> v.x() >> v.y() >> v.z() >> v.w(); return *this; }
InputStream& InputStream::operator>>( osg::Vec2f& v )
{ *this >> v.x() >> v.y(); return *this; }
InputStream& InputStream::operator>>( osg::Vec3f& v )
{ *this >> v.x() >> v.y() >> v.z(); return *this; }
InputStream& InputStream::operator>>( osg::Vec4f& v )
{ *this >> v.x() >> v.y() >> v.z() >> v.w(); return *this; }
InputStream& InputStream::operator>>( osg::Vec2d& v )
{ *this >> v.x() >> v.y(); return *this; }
InputStream& InputStream::operator>>( osg::Vec3d& v )
{ *this >> v.x() >> v.y() >> v.z(); return *this; }
InputStream& InputStream::operator>>( osg::Vec4d& v )
{ *this >> v.x() >> v.y() >> v.z() >> v.w(); return *this; }
InputStream& InputStream::operator>>( osg::Quat& q )
{ *this >> q.x() >> q.y() >> q.z() >> q.w(); return *this; }
InputStream& InputStream::operator>>( osg::Plane& p )
{
double p0, p1, p2, p3; *this >> p0 >> p1 >> p2 >> p3;
p.set( p0, p1, p2, p3 ); return *this;
}
InputStream& InputStream::operator>>( osg::Matrixf& mat )
{
*this >> PROPERTY("Matrixf") >> BEGIN_BRACKET;
for ( int r=0; r<4; ++r )
{
*this >> mat(r, 0) >> mat(r, 1) >> mat(r, 2) >> mat(r, 3);
}
*this >> END_BRACKET;
return *this;
}
InputStream& InputStream::operator>>( osg::Matrixd& mat )
{
*this >> PROPERTY("Matrixd") >> BEGIN_BRACKET;
for ( int r=0; r<4; ++r )
{
*this >> mat(r, 0) >> mat(r, 1) >> mat(r, 2) >> mat(r, 3);
}
*this >> END_BRACKET;
return *this;
}
osg::Array* InputStream::readArray()
{
osg::ref_ptr<osg::Array> array = NULL;
unsigned int id = 0;
*this >> PROPERTY("ArrayID") >> id;
ArrayMap::iterator itr = _arrayMap.find( id );
if ( itr!=_arrayMap.end() ) return itr->second.get();
DEF_MAPPEE(ArrayType, type);
*this >> type;
switch ( type.get() )
{
case ID_BYTE_ARRAY:
{
osg::ByteArray* ba = new osg::ByteArray;
readArrayImplementation( ba, CHAR_SIZE, true );
array = ba;
}
break;
case ID_UBYTE_ARRAY:
{
osg::UByteArray* uba = new osg::UByteArray;
readArrayImplementation( uba, CHAR_SIZE, true );
array = uba;
}
break;
case ID_SHORT_ARRAY:
{
osg::ShortArray* sa = new osg::ShortArray;
readArrayImplementation( sa, SHORT_SIZE, true );
array = sa;
}
break;
case ID_USHORT_ARRAY:
{
osg::UShortArray* usa = new osg::UShortArray;
readArrayImplementation( usa, SHORT_SIZE, true );
array = usa;
}
break;
case ID_INT_ARRAY:
{
osg::IntArray* ia = new osg::IntArray;
readArrayImplementation( ia, INT_SIZE, true );
array = ia;
}
break;
case ID_UINT_ARRAY:
{
osg::UIntArray* uia = new osg::UIntArray;
readArrayImplementation( uia, INT_SIZE, true );
array = uia;
}
break;
case ID_FLOAT_ARRAY:
{
osg::FloatArray* fa = new osg::FloatArray;
readArrayImplementation( fa, FLOAT_SIZE, true );
array = fa;
}
break;
case ID_DOUBLE_ARRAY:
{
osg::DoubleArray* da = new osg::DoubleArray;
readArrayImplementation( da, DOUBLE_SIZE, true );
array = da;
}
break;
case ID_VEC2B_ARRAY:
{
osg::Vec2bArray* va = new osg::Vec2bArray;
readArrayImplementation( va, 2*CHAR_SIZE );
array = va;
}
break;
case ID_VEC3B_ARRAY:
{
osg::Vec3bArray* va = new osg::Vec3bArray;
readArrayImplementation( va, 3*CHAR_SIZE );
array = va;
}
break;
case ID_VEC4B_ARRAY:
{
osg::Vec4bArray* va = new osg::Vec4bArray;
readArrayImplementation( va, 4*CHAR_SIZE );
array = va;
}
break;
case ID_VEC4UB_ARRAY:
{
osg::Vec4ubArray* va = new osg::Vec4ubArray;
readArrayImplementation( va, 4*CHAR_SIZE );
array = va;
}
break;
case ID_VEC2S_ARRAY:
{
osg::Vec2sArray* va = new osg::Vec2sArray;
readArrayImplementation( va, 2*SHORT_SIZE );
array = va;
}
break;
case ID_VEC3S_ARRAY:
{
osg::Vec3sArray* va = new osg::Vec3sArray;
readArrayImplementation( va, 3*SHORT_SIZE );
array = va;
}
break;
case ID_VEC4S_ARRAY:
{
osg::Vec4sArray* va = new osg::Vec4sArray;
readArrayImplementation( va, 4*SHORT_SIZE );
array = va;
}
break;
case ID_VEC2_ARRAY:
{
osg::Vec2Array* va = new osg::Vec2Array;
readArrayImplementation( va, 2*FLOAT_SIZE );
array = va;
}
break;
case ID_VEC3_ARRAY:
{
osg::Vec3Array* va = new osg::Vec3Array;
readArrayImplementation( va, 3*FLOAT_SIZE );
array = va;
}
break;
case ID_VEC4_ARRAY:
{
osg::Vec4Array* va = new osg::Vec4Array;
readArrayImplementation( va, 4*FLOAT_SIZE );
array = va;
}
break;
case ID_VEC2D_ARRAY:
{
osg::Vec2dArray* va = new osg::Vec2dArray;
readArrayImplementation( va, 2*DOUBLE_SIZE );
array = va;
}
break;
case ID_VEC3D_ARRAY:
{
osg::Vec3dArray* va = new osg::Vec3dArray;
readArrayImplementation( va, 3*DOUBLE_SIZE );
array = va;
}
break;
case ID_VEC4D_ARRAY:
{
osg::Vec4dArray* va = new osg::Vec4dArray;
readArrayImplementation( va, 4*DOUBLE_SIZE );
array = va;
}
break;
default:
throwException( "InputStream::readArray(): Unsupported array type." );
}
if ( getException() ) return NULL;
_arrayMap[id] = array;
return array.release();
}
osg::PrimitiveSet* InputStream::readPrimitiveSet()
{
osg::ref_ptr<osg::PrimitiveSet> primitive = NULL;
DEF_MAPPEE(PrimitiveType, type);
DEF_MAPPEE(PrimitiveType, mode);
*this >> type >> mode;
switch ( type.get() )
{
case ID_DRAWARRAYS:
{
int first = 0, count = 0;
*this >> first >> count;
osg::DrawArrays* da = new osg::DrawArrays( mode.get(), first, count );
primitive = da;
}
break;
case ID_DRAWARRAY_LENGTH:
{
int first = 0, value = 0; unsigned int size = 0;
*this >> first >> size >> BEGIN_BRACKET;
osg::DrawArrayLengths* dl = new osg::DrawArrayLengths( mode.get(), first );
for ( unsigned int i=0; i<size; ++i )
{
*this >> value;
dl->push_back( value );
}
*this >> END_BRACKET;
primitive = dl;
}
break;
case ID_DRAWELEMENTS_UBYTE:
{
osg::DrawElementsUByte* de = new osg::DrawElementsUByte( mode.get() );
unsigned int size = 0; unsigned char value = 0;
*this >> size >> BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
*this >> value;
de->push_back( value );
}
*this >> END_BRACKET;
primitive = de;
}
break;
case ID_DRAWELEMENTS_USHORT:
{
osg::DrawElementsUShort* de = new osg::DrawElementsUShort( mode.get() );
unsigned int size = 0; unsigned short value = 0;
*this >> size >> BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
*this >> value;
de->push_back( value );
}
*this >> END_BRACKET;
primitive = de;
}
break;
case ID_DRAWELEMENTS_UINT:
{
osg::DrawElementsUInt* de = new osg::DrawElementsUInt( mode.get() );
unsigned int size = 0, value = 0;
*this >> size >> BEGIN_BRACKET;
for ( unsigned int i=0; i<size; ++i )
{
*this >> value;
de->push_back( value );
}
*this >> END_BRACKET;
primitive = de;
}
break;
default:
throwException( "InputStream::readPrimitiveSet(): Unsupported array type." );
}
if ( getException() ) return NULL;
return primitive.release();
}
osg::Image* InputStream::readImage()
{
unsigned int id = 0;
*this >> PROPERTY("ImageID") >> id;
if ( getException() ) return NULL;
IdentifierMap::iterator itr = _identifierMap.find( id );
if ( itr!=_identifierMap.end() )
{
advanceToCurrentEndBracket();
return static_cast<osg::Image*>( itr->second.get() );
}
std::string name;
int writeHint, decision = IMAGE_EXTERNAL;
*this >> PROPERTY("FileName"); readWrappedString(name);
*this >> PROPERTY("WriteHint") >> writeHint >> decision;
if ( getException() ) return NULL;
osg::ref_ptr<osg::Image> image = NULL;
bool readFromExternal = true;
switch ( decision )
{
case IMAGE_INLINE_DATA:
if ( isBinary() )
{
image = new osg::Image;
// _origin, _s & _t & _r, _internalTextureFormat
int origin, s, t, r, internalFormat;
*this >> origin >> s >> t >> r >> internalFormat;
// _pixelFormat, _dataType, _packing, _allocationMode
int pixelFormat, dataType, packing, mode;
*this >> pixelFormat >> dataType >> packing >> mode;
// _data
unsigned int size = 0; *this >> size;
if ( size )
{
char* data = new char[size];
if ( !data )
throwException( "InputStream::readImage() Out of memory." );
if ( getException() ) return NULL;
readCharArray( data, size );
image->setOrigin( (osg::Image::Origin)origin );
image->setImage( s, t, r, internalFormat, pixelFormat, dataType,
(unsigned char*)data, (osg::Image::AllocationMode)mode, packing );
}
// _mipmapData
unsigned int levelSize = readSize();
osg::Image::MipmapDataType levels(levelSize);
for ( unsigned int i=0; i<levelSize; ++i )
{
*this >> levels[i];
}
if ( levelSize>0 )
image->setMipmapLevels( levels );
readFromExternal = false;
}
break;
case IMAGE_INLINE_FILE:
if ( isBinary() )
{
unsigned int size = readSize();
if ( size>0 )
{
char* data = new char[size];
if ( !data )
throwException( "InputStream::readImage(): Out of memory." );
if ( getException() ) return NULL;
readCharArray( data, size );
std::string ext = osgDB::getFileExtension( name );
osgDB::ReaderWriter* reader =
osgDB::Registry::instance()->getReaderWriterForExtension( ext );
if ( reader )
{
std::stringstream inputStream;
inputStream.write( data, size );
osgDB::ReaderWriter::ReadResult rr = reader->readImage( inputStream );
if ( rr.validImage() )
image = rr.takeImage();
else
{
OSG_WARN << "InputStream::readImage(): "
<< rr.message() << std::endl;
}
}
else
{
OSG_WARN << "InputStream::readImage(): Unable to find a plugin for "
<< ext << std::endl;
}
delete[] data;
}
readFromExternal = false;
}
break;
case IMAGE_EXTERNAL: case IMAGE_WRITE_OUT:
break;
default:
break;
}
if ( readFromExternal )
{
image = osgDB::readImageFile( name, getOptions() );
if ( !image && _forceReadingImage ) image = new osg::Image;
}
if ( image.valid() )
{
image->setFileName( name );
image->setWriteHint( (osg::Image::WriteHint)writeHint );
}
image = static_cast<osg::Image*>( readObject(image.get()) );
return image.release();
}
osg::Object* InputStream::readObject( osg::Object* existingObj )
{
std::string className;
unsigned int id = 0;
*this >> className >> BEGIN_BRACKET >> PROPERTY("UniqueID") >> id;
if ( getException() ) return NULL;
IdentifierMap::iterator itr = _identifierMap.find( id );
if ( itr!=_identifierMap.end() )
{
advanceToCurrentEndBracket();
return itr->second.get();
}
ObjectWrapper* wrapper = Registry::instance()->getObjectWrapperManager()->findWrapper( className );
if ( !wrapper )
{
OSG_WARN << "InputStream::readObject(): Unsupported wrapper class "
<< className << std::endl;
advanceToCurrentEndBracket();
return NULL;
}
_fields.push_back( className );
osg::ref_ptr<osg::Object> obj = existingObj ? existingObj : wrapper->getProto()->cloneType();
if ( obj.valid() )
{
_identifierMap[id] = obj;
const StringList& associates = wrapper->getAssociates();
for ( StringList::const_iterator itr=associates.begin(); itr!=associates.end(); ++itr )
{
ObjectWrapper* assocWrapper = Registry::instance()->getObjectWrapperManager()->findWrapper(*itr);
if ( !assocWrapper )
{
OSG_WARN << "InputStream::readObject(): Unsupported associated class "
<< *itr << std::endl;
continue;
}
_fields.push_back( assocWrapper->getName() );
assocWrapper->read( *this, *obj );
if ( getException() ) return NULL;
_fields.pop_back();
}
}
advanceToCurrentEndBracket();
_fields.pop_back();
return obj.release();
}
void InputStream::readSchema( std::istream& fin )
{
// Read from external ascii stream
std::string line;
while ( std::getline(fin, line) )
{
if ( line[0]=='#' ) continue; // Comment
StringList keyAndValue;
split( line, keyAndValue, '=' );
if ( keyAndValue.size()<2 ) continue;
setWrapperSchema( osgDB::trimEnclosingSpaces(keyAndValue[0]),
osgDB::trimEnclosingSpaces(keyAndValue[1]) );
}
}
InputStream::ReadType InputStream::start( InputIterator* inIterator )
{
_fields.clear();
_fields.push_back( "Start" );
ReadType type = READ_UNKNOWN;
_in = inIterator;
if ( !_in )
throwException( "InputStream: Null stream specified." );
if ( getException() ) return type;
// Check OSG header information
unsigned int version = 0;
if ( isBinary() )
{
unsigned int typeValue;
*this >> typeValue >> version;
type = static_cast<ReadType>(typeValue);
unsigned int attributes; *this >> attributes;
if ( attributes&0x1 ) _useFloatMatrix = false;
if ( attributes&0x2 ) _useSchemaData = true;
}
if ( !isBinary() )
{
std::string typeString; *this >> typeString;
if ( typeString=="Scene" ) type = READ_SCENE;
else if ( typeString=="Image" ) type = READ_IMAGE;
else if ( typeString=="Object" ) type = READ_OBJECT;
std::string osgName, osgVersion;
*this >> PROPERTY("#Version") >> version;
*this >> PROPERTY("#Generator") >> osgName >> osgVersion;
}
// Check file version
if ( version!=PLUGIN_VERSION )
{
OSG_WARN << "InputStream: Input data version " << version
<< " may be incompatible with current reader version "
<< PLUGIN_VERSION << std::endl;
}
_fields.pop_back();
return type;
}
void InputStream::decompress()
{
if ( !isBinary() ) return;
_fields.clear();
std::string compressorName; *this >> compressorName;
if ( compressorName!="0" )
{
std::string data;
_fields.push_back( "Decompression" );
BaseCompressor* compressor = Registry::instance()->getObjectWrapperManager()->findCompressor(compressorName);
if ( !compressor )
{
OSG_WARN << "InputStream::decompress(): No such compressor "
<< compressorName << std::endl;
}
if ( !compressor->decompress(*(_in->getStream()), data) )
throwException( "InputStream: Failed to decompress stream." );
if ( getException() ) return;
_dataDecompress = new std::stringstream(data);
_in->setStream( _dataDecompress );
_fields.pop_back();
}
if ( _useSchemaData )
{
_fields.push_back( "SchemaData" );
std::string schemaSource; *this >> schemaSource;
std::istringstream iss( schemaSource );
readSchema( iss );
_fields.pop_back();
}
}
// PROTECTED METHODS
void InputStream::setWrapperSchema( const std::string& name, const std::string& properties )
{
ObjectWrapper* wrapper = Registry::instance()->getObjectWrapperManager()->findWrapper(name);
if ( !wrapper )
{
OSG_WARN << "InputStream::setSchema(): Unsupported wrapper class "
<< name << std::endl;
return;
}
StringList schema;
split( properties, schema );
wrapper->readSchema( schema );
}
void InputStream::resetSchema()
{
const ObjectWrapperManager::WrapperMap& wrappers = Registry::instance()->getObjectWrapperManager()->getWrapperMap();
for ( ObjectWrapperManager::WrapperMap::const_iterator itr=wrappers.begin();
itr!=wrappers.end(); ++itr )
{
ObjectWrapper* wrapper = itr->second.get();
wrapper->resetSchema();
}
}
template<typename T>
void InputStream::readArrayImplementation( T* a, int read_size, bool useByteSwap )
{
int size = 0;
*this >> size >> BEGIN_BRACKET;
if ( size )
{
a->resize( size );
if ( isBinary() )
{
readCharArray( (char*)&((*a)[0]), read_size*size ); checkStream();
if ( useByteSwap && _byteSwap )
{
for ( int i=0; i<size; ++i )
osg::swapBytes( (char*)&((*a)[i]), read_size );
}
}
else
{
for ( int i=0; i<size; ++i )
*this >> (*a)[i];
}
}
*this >> END_BRACKET;
}
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
// Written by Wang Rui, (C) 2010
#ifndef OSGDB_INPUTSTREAM
#define OSGDB_INPUTSTREAM
#include <osg/Endian>
#include <osg/Vec2>
#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/Quat>
#include <osg/Matrix>
#include <osg/Array>
#include <osg/PrimitiveSet>
#include <osgDB/ReaderWriter>
#include <osgDB/StreamOperator>
#include <iostream>
#include <sstream>
namespace osgDB
{
class InputException : public osg::Referenced
{
public:
InputException( const std::vector<std::string>& fields, const std::string& err ) : _error(err)
{
for ( unsigned int i=0; i<fields.size(); ++i )
{
_field += fields[i];
_field += " ";
}
}
const std::string& getField() const { return _field; }
const std::string& getError() const { return _error; }
protected:
std::string _field;
std::string _error;
};
class OSGDB_EXPORT InputStream
{
public:
typedef std::map< unsigned int, osg::ref_ptr<osg::Array> > ArrayMap;
typedef std::map< unsigned int, osg::ref_ptr<osg::Object> > IdentifierMap;
enum ReadType
{
READ_UNKNOWN = 0,
READ_SCENE,
READ_IMAGE,
READ_OBJECT
};
InputStream( const osgDB::Options* options );
virtual ~InputStream();
bool isBinary() const { return _in->isBinary(); }
bool getUseFloatMatrix() const { return _useFloatMatrix; }
const osgDB::Options* getOptions() const { return _options.get(); }
// Serialization related functions
InputStream& operator>>( bool& b ) { _in->readBool(b); checkStream(); return *this; }
InputStream& operator>>( char& c ) { _in->readChar(c); checkStream(); return *this; }
InputStream& operator>>( signed char& c ) { _in->readSChar(c); checkStream(); return *this; }
InputStream& operator>>( unsigned char& c ) { _in->readUChar(c); checkStream(); return *this; }
InputStream& operator>>( short& s ) { _in->readShort(s); checkStream(); return *this; }
InputStream& operator>>( unsigned short& s ) { _in->readUShort(s); checkStream(); return *this; }
InputStream& operator>>( int& i ) { _in->readInt(i); checkStream(); return *this; }
InputStream& operator>>( unsigned int& i ) { _in->readUInt(i); checkStream(); return *this; }
InputStream& operator>>( long& l ) { _in->readLong(l); checkStream(); return *this; }
InputStream& operator>>( unsigned long& l ) { _in->readULong(l); checkStream(); return *this; }
InputStream& operator>>( float& f ) { _in->readFloat(f); checkStream(); return *this; }
InputStream& operator>>( double& d ) { _in->readDouble(d); checkStream(); return *this; }
InputStream& operator>>( std::string& s ) { _in->readString(s); checkStream(); return *this; }
InputStream& operator>>( std::istream& (*fn)(std::istream&) ) { _in->readStream(fn); checkStream(); return *this; }
InputStream& operator>>( std::ios_base& (*fn)(std::ios_base&) ) { _in->readBase(fn); checkStream(); return *this; }
InputStream& operator>>( ObjectGLenum& value ) { _in->readGLenum(value); checkStream(); return *this; }
InputStream& operator>>( ObjectProperty& prop ) { _in->readProperty(prop); checkStream(); return *this; }
InputStream& operator>>( ObjectMark& mark ) { _in->readMark(mark); checkStream(); return *this; }
InputStream& operator>>( osg::Vec2b& v );
InputStream& operator>>( osg::Vec3b& v );
InputStream& operator>>( osg::Vec4b& v );
InputStream& operator>>( osg::Vec4ub& v );
InputStream& operator>>( osg::Vec2s& v );
InputStream& operator>>( osg::Vec3s& v );
InputStream& operator>>( osg::Vec4s& v );
InputStream& operator>>( osg::Vec2f& v );
InputStream& operator>>( osg::Vec3f& v );
InputStream& operator>>( osg::Vec4f& v );
InputStream& operator>>( osg::Vec2d& v );
InputStream& operator>>( osg::Vec3d& v );
InputStream& operator>>( osg::Vec4d& v );
InputStream& operator>>( osg::Quat& q );
InputStream& operator>>( osg::Plane& p );
InputStream& operator>>( osg::Matrixf& mat );
InputStream& operator>>( osg::Matrixd& mat );
InputStream& operator>>( osg::Array*& a ) { a = readArray(); return *this; }
InputStream& operator>>( osg::Image*& img ) { img = readImage(); return *this; }
InputStream& operator>>( osg::PrimitiveSet*& p ) { p = readPrimitiveSet(); return *this; }
InputStream& operator>>( osg::Object*& obj ) { obj = readObject(); return *this; }
InputStream& operator>>( osg::ref_ptr<osg::Array>& ptr ) { ptr = readArray(); return *this; }
InputStream& operator>>( osg::ref_ptr<osg::Image>& ptr ) { ptr = readImage(); return *this; }
InputStream& operator>>( osg::ref_ptr<osg::PrimitiveSet>& ptr ) { ptr = readPrimitiveSet(); return *this; }
template<typename T> InputStream& operator>>( osg::ref_ptr<T>& ptr )
{ ptr = static_cast<T*>(readObject()); return *this; }
// Convenient methods for reading
bool matchString( const std::string& str ) { return _in->matchString(str); }
void advanceToCurrentEndBracket() { _in->advanceToCurrentEndBracket(); }
void readWrappedString( std::string& str ) { _in->readWrappedString(str); checkStream(); }
void readCharArray( char* s, unsigned int size ) { _in->readCharArray(s, size); }
// readSize() use unsigned int for all sizes.
unsigned int readSize() { unsigned int size; *this>>size; return size; }
// Global reading functions
osg::Array* readArray();
osg::PrimitiveSet* readPrimitiveSet();
osg::Image* readImage();
osg::Object* readObject( osg::Object* existingObj=0 );
ReadType start( InputIterator* );
void decompress();
// Schema handlers
void readSchema( std::istream& fin );
void resetSchema();
// Exception handlers
inline void throwException( const std::string& msg );
const InputException* getException() const { return _exception.get(); }
protected:
inline void checkStream();
void setWrapperSchema( const std::string& name, const std::string& properties );
template<typename T>
void readArrayImplementation( T* a, int read_size, bool useByteSwap=false );
ArrayMap _arrayMap;
IdentifierMap _identifierMap;
int _byteSwap;
bool _useFloatMatrix;
bool _useSchemaData;
bool _forceReadingImage;
std::vector<std::string> _fields;
osg::ref_ptr<InputIterator> _in;
osg::ref_ptr<InputException> _exception;
osg::ref_ptr<const osgDB::Options> _options;
// store here to avoid a new and a leak in InputStream::decompress
std::stringstream* _dataDecompress;
};
void InputStream::throwException( const std::string& msg )
{
_exception = new InputException(_fields, msg);
}
void InputStream::checkStream()
{
_in->checkStream();
if ( _in->isFailed() )
throwException( "InputStream: Failed to read from stream." );
}
}
#endif
signature.asc
Description: This is a digitally signed message part
_______________________________________________ osg-submissions mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
