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

Attachment: 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

Reply via email to