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