1 #ifndef OSGDB_ASCIISTREAMOPERATOR 2 #define OSGDB_ASCIISTREAMOPERATOR 3 4 #include <ostream> 5 #include <osgDB/StreamOperator> 6 7 class AsciiOutputIterator : public osgDB::OutputIterator 8 { 9 public: AsciiOutputIterator(std::ostream * ostream,int precision)10 AsciiOutputIterator( std::ostream* ostream, int precision ) 11 : _readyForIndent(false), _indent(0) 12 { 13 _out = ostream; 14 if (precision>0) _out->precision(precision); 15 } 16 ~AsciiOutputIterator()17 virtual ~AsciiOutputIterator() {} 18 isBinary()19 virtual bool isBinary() const { return false; } 20 writeBool(bool b)21 virtual void writeBool( bool b ) 22 { 23 indentIfRequired(); 24 if ( b ) *_out << "TRUE "; 25 else *_out << "FALSE "; 26 } 27 writeChar(char c)28 virtual void writeChar( char c ) 29 { indentIfRequired(); *_out << (short)c << ' '; } 30 writeUChar(unsigned char c)31 virtual void writeUChar( unsigned char c ) 32 { indentIfRequired(); *_out << (unsigned short)c << ' '; } 33 writeShort(short s)34 virtual void writeShort( short s ) 35 { indentIfRequired(); *_out << s << ' '; } 36 writeUShort(unsigned short s)37 virtual void writeUShort( unsigned short s ) 38 { indentIfRequired(); *_out << s << ' '; } 39 writeInt(int i)40 virtual void writeInt( int i ) 41 { indentIfRequired(); *_out << i << ' '; } 42 writeUInt(unsigned int i)43 virtual void writeUInt( unsigned int i ) 44 { indentIfRequired(); *_out << i << ' '; } 45 writeLong(long l)46 virtual void writeLong( long l ) 47 { indentIfRequired(); *_out << l << ' '; } 48 writeULong(unsigned long l)49 virtual void writeULong( unsigned long l ) 50 { indentIfRequired(); *_out << l << ' '; } 51 writeInt64(GLint64 ll)52 virtual void writeInt64( GLint64 ll ) 53 { indentIfRequired(); *_out << ll << ' '; } 54 writeUInt64(GLuint64 ull)55 virtual void writeUInt64( GLuint64 ull ) 56 { indentIfRequired(); *_out << ull << ' '; } 57 writeFloat(float f)58 virtual void writeFloat( float f ) 59 { indentIfRequired(); *_out << f << ' '; } 60 writeDouble(double d)61 virtual void writeDouble( double d ) 62 { indentIfRequired(); *_out << d << ' '; } 63 writeString(const std::string & s)64 virtual void writeString( const std::string& s ) 65 { indentIfRequired(); *_out << s << ' '; } 66 writeStream(std::ostream & (* fn)(std::ostream &))67 virtual void writeStream( std::ostream& (*fn)(std::ostream&) ) 68 { 69 indentIfRequired(); *_out << fn; 70 if ( isEndl( fn ) ) 71 { 72 _readyForIndent = true; 73 } 74 } 75 writeBase(std::ios_base & (* fn)(std::ios_base &))76 virtual void writeBase( std::ios_base& (*fn)(std::ios_base&) ) 77 { 78 indentIfRequired(); *_out << fn; 79 } 80 writeGLenum(const osgDB::ObjectGLenum & value)81 virtual void writeGLenum( const osgDB::ObjectGLenum& value ) 82 { 83 GLenum e = value.get(); 84 const std::string& enumString = osgDB::Registry::instance()->getObjectWrapperManager()->getString("GL", e); 85 indentIfRequired(); *_out << enumString << ' '; 86 } 87 writeProperty(const osgDB::ObjectProperty & prop)88 virtual void writeProperty( const osgDB::ObjectProperty& prop ) 89 { 90 std::string enumString = prop._name; 91 if ( prop._mapProperty ) 92 { 93 enumString = osgDB::Registry::instance()->getObjectWrapperManager()->getString(prop._name, prop._value); 94 } 95 indentIfRequired(); *_out << enumString << ' '; 96 } 97 writeMark(const osgDB::ObjectMark & mark)98 virtual void writeMark( const osgDB::ObjectMark& mark ) 99 { 100 _indent += mark._indentDelta; 101 indentIfRequired(); *_out << mark._name; 102 } 103 writeCharArray(const char *,unsigned int)104 virtual void writeCharArray( const char* /*s*/, unsigned int /*size*/ ) {} 105 writeWrappedString(const std::string & str)106 virtual void writeWrappedString( const std::string& str ) 107 { 108 std::string wrappedStr; 109 unsigned int size = str.size(); 110 for ( unsigned int i=0; i<size; ++i ) 111 { 112 char ch = str[i]; 113 if ( ch=='\"' ) wrappedStr += '\\'; 114 else if ( ch=='\\' ) wrappedStr += '\\'; 115 wrappedStr += ch; 116 } 117 118 wrappedStr.insert( std::string::size_type(0), 1, '\"' ); 119 wrappedStr += '\"'; 120 121 indentIfRequired(); 122 writeString( wrappedStr ); 123 } 124 125 protected: 126 indentIfRequired()127 inline void indentIfRequired() 128 { 129 if ( _readyForIndent ) 130 { 131 for (int i=0; i<_indent; ++i) 132 *_out << ' '; 133 _readyForIndent = false; 134 } 135 } 136 137 bool _readyForIndent; 138 int _indent; 139 }; 140 141 class AsciiInputIterator : public osgDB::InputIterator 142 { 143 public: AsciiInputIterator(std::istream * istream)144 AsciiInputIterator( std::istream* istream ) { _in = istream; } ~AsciiInputIterator()145 virtual ~AsciiInputIterator() {} 146 isBinary()147 virtual bool isBinary() const { return false; } 148 readBool(bool & b)149 virtual void readBool( bool& b ) 150 { 151 std::string boolString; 152 readString( boolString ); 153 if ( boolString=="TRUE" ) b = true; 154 else b = false; 155 } 156 readChar(char & c)157 virtual void readChar( char& c ) 158 { 159 short s = 0; 160 readShort( s ); 161 c = (char)s; 162 } 163 readSChar(signed char & c)164 virtual void readSChar( signed char& c ) 165 { 166 short s = 0; 167 readShort( s ); 168 c = (signed char)s; 169 } 170 readUChar(unsigned char & c)171 virtual void readUChar( unsigned char& c ) 172 { 173 short s = 0; 174 readShort( s ); 175 c = (unsigned char)s; 176 } 177 readShort(short & s)178 virtual void readShort( short& s ) 179 { std::string str; readString(str); s = static_cast<short>(strtol(str.c_str(), NULL, 0)); } 180 readUShort(unsigned short & s)181 virtual void readUShort( unsigned short& s ) 182 { std::string str; readString(str); s = static_cast<unsigned short>(strtoul(str.c_str(), NULL, 0)); } 183 readInt(int & i)184 virtual void readInt( int& i ) 185 { std::string str; readString(str); i = static_cast<int>(strtol(str.c_str(), NULL, 0)); } 186 readUInt(unsigned int & i)187 virtual void readUInt( unsigned int& i ) 188 { std::string str; readString(str); i = static_cast<unsigned int>(strtoul(str.c_str(), NULL, 0)); } 189 readLong(long & l)190 virtual void readLong( long& l ) 191 { std::string str; readString(str); l = strtol(str.c_str(), NULL, 0); } 192 readULong(unsigned long & l)193 virtual void readULong( unsigned long& l ) 194 { std::string str; readString(str); l = strtoul(str.c_str(), NULL, 0); } 195 readFloat(float & f)196 virtual void readFloat( float& f ) 197 { std::string str; readString(str); f = osg::asciiToFloat(str.c_str()); } 198 readDouble(double & d)199 virtual void readDouble( double& d ) 200 { std::string str; readString(str); d = osg::asciiToDouble(str.c_str()); } 201 readString(std::string & s)202 virtual void readString( std::string& s ) 203 { 204 if ( _preReadString.empty() ) 205 *_in >> s; 206 else 207 { 208 s = _preReadString; 209 _preReadString.clear(); 210 } 211 } 212 readStream(std::istream & (* fn)(std::istream &))213 virtual void readStream( std::istream& (*fn)(std::istream&) ) 214 { *_in >> fn; } 215 readBase(std::ios_base & (* fn)(std::ios_base &))216 virtual void readBase( std::ios_base& (*fn)(std::ios_base&) ) 217 { *_in >> fn; } 218 readGLenum(osgDB::ObjectGLenum & value)219 virtual void readGLenum( osgDB::ObjectGLenum& value ) 220 { 221 GLenum e = 0; 222 std::string enumString; 223 readString( enumString ); 224 e = osgDB::Registry::instance()->getObjectWrapperManager()->getValue("GL", enumString); 225 value.set( e ); 226 } 227 readProperty(osgDB::ObjectProperty & prop)228 virtual void readProperty( osgDB::ObjectProperty& prop ) 229 { 230 int value = 0; 231 std::string enumString; 232 readString( enumString ); 233 if ( prop._mapProperty ) 234 { 235 value = osgDB::Registry::instance()->getObjectWrapperManager()->getValue(prop._name, enumString); 236 } 237 else 238 { 239 if ( prop._name!=enumString ) 240 { 241 OSG_WARN << "AsciiInputIterator::readProperty(): Unmatched property " 242 << enumString << ", expecting " << prop._name << std::endl; 243 } 244 prop._name = enumString; 245 } 246 prop.set( value ); 247 } 248 readMark(osgDB::ObjectMark &)249 virtual void readMark( osgDB::ObjectMark& /*mark*/ ) 250 { 251 std::string markString; 252 readString( markString ); 253 } 254 readCharArray(char *,unsigned int)255 virtual void readCharArray( char* /*s*/, unsigned int /*size*/ ) {} 256 readWrappedString(std::string & str)257 virtual void readWrappedString( std::string& str ) 258 { 259 char ch; 260 getCharacter( ch ); 261 262 // skip white space 263 while ( ch==' ' || (ch=='\n') || (ch=='\r')) 264 { 265 getCharacter( ch ); 266 } 267 268 if (ch=='"') 269 { 270 // we have an "wrapped string" 271 getCharacter( ch ); 272 while ( ch!='"' ) 273 { 274 if (ch=='\\') 275 { 276 getCharacter( ch ); 277 str += ch; 278 } 279 else str += ch; 280 281 getCharacter( ch ); 282 } 283 } 284 else 285 { 286 // we have an unwrapped string, read to first space or end of line 287 while ( (ch!=' ') && (ch!=0) && (ch!='\n') ) 288 { 289 str += ch; 290 getCharacter( ch ); 291 } 292 } 293 } 294 matchString(const std::string & str)295 virtual bool matchString( const std::string& str ) 296 { 297 if ( _preReadString.empty() ) 298 *_in >> _preReadString; 299 300 if ( _preReadString==str ) 301 { 302 _preReadString.clear(); 303 return true; 304 } 305 return false; 306 } 307 advanceToCurrentEndBracket()308 virtual void advanceToCurrentEndBracket() 309 { 310 std::string passString; 311 unsigned int blocks = 0; 312 while ( !_in->eof() ) 313 { 314 passString.clear(); 315 readString( passString ); 316 317 if ( passString=="}" ) 318 { 319 if ( blocks<=0 ) return; 320 else blocks--; 321 } 322 else if ( passString=="{" ) 323 blocks++; 324 } 325 } 326 327 protected: getCharacter(char & ch)328 void getCharacter( char& ch ) 329 { 330 if ( !_preReadString.empty() ) 331 { 332 ch = _preReadString[0]; 333 _preReadString.erase( _preReadString.begin() ); 334 } 335 else 336 { 337 _in->get( ch ); 338 checkStream(); 339 } 340 } 341 342 std::string _preReadString; 343 }; 344 345 #endif 346