From 9529b14f3c72f9062cde55ba2cbd7afd39d2ee67 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 15 Jul 2011 09:16:33 +0000 Subject: [PATCH] From Wang Rui, merged from svn/trunk revision 12688. "The files attached should be separately put into the directories src/osgPlugins/osg and src/osgWrappers/serializers/osgSim. They fix a serious infinite loop problem that may be caused by the stream buffer mechanism under Windows and some osgSim wrapper bugs pointed by Andreas. I've asked the community to help test them and hope now we can solve these recent .osgt file reading issues." --- src/osgPlugins/osg/AsciiStreamOperator.h | 64 +++++++++++-------- .../serializers/osgSim/LightPointNode.cpp | 34 ++++++++-- .../serializers/osgSim/MultiSwitch.cpp | 3 +- 3 files changed, 69 insertions(+), 32 deletions(-) diff --git a/src/osgPlugins/osg/AsciiStreamOperator.h b/src/osgPlugins/osg/AsciiStreamOperator.h index 9b21b19b6..10b74a4ce 100644 --- a/src/osgPlugins/osg/AsciiStreamOperator.h +++ b/src/osgPlugins/osg/AsciiStreamOperator.h @@ -139,7 +139,7 @@ public: virtual void readBool( bool& b ) { std::string boolString; - *_in >> boolString; + readString( boolString ); if ( boolString=="TRUE" ) b = true; else b = false; } @@ -147,50 +147,58 @@ public: virtual void readChar( char& c ) { short s = 0; - *_in >> s; + readShort( s ); c = (char)s; } virtual void readSChar( signed char& c ) { short s = 0; - *_in >> s; + readShort( s ); c = (signed char)s; } virtual void readUChar( unsigned char& c ) { short s = 0; - *_in >> s; + readShort( s ); c = (unsigned char)s; } virtual void readShort( short& s ) - { std::string str; *_in >> str; s = static_cast(strtol(str.c_str(), NULL, 0)); } + { std::string str; readString(str); s = static_cast(strtol(str.c_str(), NULL, 0)); } virtual void readUShort( unsigned short& s ) - { std::string str; *_in >> str; s = static_cast(strtoul(str.c_str(), NULL, 0)); } + { std::string str; readString(str); s = static_cast(strtoul(str.c_str(), NULL, 0)); } virtual void readInt( int& i ) - { std::string str; *_in >> str; i = static_cast(strtol(str.c_str(), NULL, 0)); } + { std::string str; readString(str); i = static_cast(strtol(str.c_str(), NULL, 0)); } virtual void readUInt( unsigned int& i ) - { std::string str; *_in >> str; i = static_cast(strtoul(str.c_str(), NULL, 0)); } + { std::string str; readString(str); i = static_cast(strtoul(str.c_str(), NULL, 0)); } virtual void readLong( long& l ) - { std::string str; *_in >> str; l = strtol(str.c_str(), NULL, 0); } + { std::string str; readString(str); l = strtol(str.c_str(), NULL, 0); } virtual void readULong( unsigned long& l ) - { std::string str; *_in >> str; l = strtoul(str.c_str(), NULL, 0); } + { std::string str; readString(str); l = strtoul(str.c_str(), NULL, 0); } virtual void readFloat( float& f ) - { std::string str; *_in >> str; f = osg::asciiToFloat(str.c_str()); } + { std::string str; readString(str); f = osg::asciiToFloat(str.c_str()); } virtual void readDouble( double& d ) - { std::string str; *_in >> str; d = osg::asciiToDouble(str.c_str()); } + { std::string str; readString(str); d = osg::asciiToDouble(str.c_str()); } virtual void readString( std::string& s ) - { *_in >> s; } + { + if ( _preReadString.empty() ) + *_in >> s; + else + { + s = _preReadString; + _preReadString.clear(); + } + } virtual void readStream( std::istream& (*fn)(std::istream&) ) { *_in >> fn; } @@ -202,7 +210,7 @@ public: { GLenum e = 0; std::string enumString; - *_in >> enumString; + readString( enumString ); e = osgDB::Registry::instance()->getObjectWrapperManager()->getValue("GL", enumString); value.set( e ); } @@ -211,7 +219,7 @@ public: { int value = 0; std::string enumString; - *_in >> enumString; + readString( enumString ); if ( prop._mapProperty ) { value = osgDB::Registry::instance()->getObjectWrapperManager()->getValue(prop._name, enumString); @@ -231,13 +239,19 @@ public: virtual void readMark( osgDB::ObjectMark& mark ) { std::string markString; - *_in >> markString; + readString( markString ); } virtual void readCharArray( char* s, unsigned int size ) {} virtual void readWrappedString( std::string& str ) { + if ( !_preReadString.empty() ) + { + str = _preReadString; + return; + } + char ch; _in->get( ch ); checkStream(); @@ -276,16 +290,13 @@ public: virtual bool matchString( const std::string& str ) { - std::string s; readString(s); - if ( s==str ) return true; - else + if ( _preReadString.empty() ) + *_in >> _preReadString; + + if ( _preReadString==str ) { - // originally "_in->seekg( -(int)(s.length()), std::ios::cur );" was used below but - // problems under windows occurred when reading ascii files with unix line endings. - // The workaround for this problem was to unget each of the characters in term, - // hacky yes, but at least it works! - for (unsigned int i = 0; i < s.length(); ++i) - _in->unget(); + _preReadString.clear(); + return true; } return false; } @@ -308,6 +319,9 @@ public: blocks++; } } + +protected: + std::string _preReadString; }; #endif diff --git a/src/osgWrappers/serializers/osgSim/LightPointNode.cpp b/src/osgWrappers/serializers/osgSim/LightPointNode.cpp index c279e2c0a..389c63431 100644 --- a/src/osgWrappers/serializers/osgSim/LightPointNode.cpp +++ b/src/osgWrappers/serializers/osgSim/LightPointNode.cpp @@ -22,10 +22,20 @@ static bool readLightPointList( osgDB::InputStream& is, osgSim::LightPointNode& is >> osgDB::PROPERTY("Attributes") >> pt._on >> blendingMode >> pt._intensity >> pt._radius; pt._blendingMode = (osgSim::LightPoint::BlendingMode)blendingMode; - is >> osgDB::PROPERTY("Sector"); - pt._sector = dynamic_cast( is.readObject() ); - is >> osgDB::PROPERTY("BlinkSequence"); - pt._blinkSequence = dynamic_cast( is.readObject() ); + bool hasObject = false; is >> osgDB::PROPERTY("Sector") >> hasObject; + if ( hasObject ) + { + is >> osgDB::BEGIN_BRACKET; + pt._sector = dynamic_cast( is.readObject() ); + is >> osgDB::END_BRACKET; + } + hasObject = false; is >> osgDB::PROPERTY("BlinkSequence") >> hasObject; + if ( hasObject ) + { + is >> osgDB::BEGIN_BRACKET; + pt._blinkSequence = dynamic_cast( is.readObject() ); + is >> osgDB::END_BRACKET; + } is >> osgDB::END_BRACKET; node.addLightPoint( pt ); } @@ -45,8 +55,20 @@ static bool writeLightPointList( osgDB::OutputStream& os, const osgSim::LightPoi os << osgDB::PROPERTY("Color") << pt._color << std::endl; os << osgDB::PROPERTY("Attributes") << pt._on << (int)pt._blendingMode << pt._intensity << pt._radius << std::endl; - os << osgDB::PROPERTY("Sector"); os.writeObject( pt._sector.get() ); - os << osgDB::PROPERTY("BlinkSequence"); os.writeObject( pt._blinkSequence.get() ); + os << osgDB::PROPERTY("Sector") << (pt._sector!=NULL); + if ( pt._sector!=NULL ) + { + os << osgDB::BEGIN_BRACKET << std::endl; + os.writeObject( pt._sector.get() ); + os << osgDB::END_BRACKET << std::endl; + } + os << osgDB::PROPERTY("BlinkSequence") << (pt._blinkSequence!=NULL); + if ( pt._blinkSequence!=NULL ) + { + os << osgDB::BEGIN_BRACKET << std::endl; + os.writeObject( pt._blinkSequence.get() ); + os << osgDB::END_BRACKET << std::endl; + } os << osgDB::END_BRACKET << std::endl; } os << osgDB::END_BRACKET << std::endl; diff --git a/src/osgWrappers/serializers/osgSim/MultiSwitch.cpp b/src/osgWrappers/serializers/osgSim/MultiSwitch.cpp index 8237d1088..f624ea512 100644 --- a/src/osgWrappers/serializers/osgSim/MultiSwitch.cpp +++ b/src/osgWrappers/serializers/osgSim/MultiSwitch.cpp @@ -23,6 +23,7 @@ static bool readValues( osgDB::InputStream& is, osgSim::MultiSwitch& node ) values.push_back( value ); } node.setValueList( i, values ); + is >> osgDB::END_BRACKET; } is >> osgDB::END_BRACKET; return true; @@ -40,7 +41,7 @@ static bool writeValues( osgDB::OutputStream& os, const osgSim::MultiSwitch& nod for ( osgSim::MultiSwitch::ValueList::const_iterator itr=values.begin(); itr!=values.end(); ++itr ) { - os << *itr; + os << *itr << std::endl; } os << osgDB::END_BRACKET << std::endl; }