KiCad PCB EDA Suite
Loading...
Searching...
No Matches
wrlproc.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2015 Cirilo Bernardo <[email protected]>
5 * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <iostream>
26#include <sstream>
27#include <wx/string.h>
28#include <wx/log.h>
29#include "wrlproc.h"
30#include <wx_filename.h>
31
32#define GETLINE \
33 do \
34 { \
35 try \
36 { \
37 char* cp = m_file->ReadLine(); \
38 \
39 if( nullptr == cp ) \
40 { \
41 m_eof = true; \
42 m_buf.clear(); \
43 } \
44 else \
45 { \
46 m_buf = cp; \
47 m_bufpos = 0; \
48 } \
49 \
50 m_fileline = m_file->LineNumber(); \
51 } \
52 catch( ... ) \
53 { \
54 m_error = " * [INFO] input line too long"; \
55 m_eof = true; \
56 m_buf.clear(); \
57 } \
58 } while( 0 )
59
60
62{
63 m_fileVersion = WRLVERSION::VRML_INVALID;
64 m_eof = false;
65 m_fileline = 0;
66 m_bufpos = 0;
67 m_file = aLineReader;
68
69 if( nullptr == aLineReader )
70 {
71 m_eof = true;
72 return;
73 }
74
75 m_error.clear();
76 wxString tname = m_file->GetSource();
77 m_filename = tname.ToUTF8();
78 wxFileName fn( tname );
79
80 if( fn.IsRelative() )
81 fn.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS );
82
83 m_filedir = fn.GetPathWithSep().ToUTF8();
84
85 m_buf.clear();
86 GETLINE;
87
88 if( m_eof )
89 return;
90
91 if( m_buf.compare( 0, 16, "#VRML V1.0 ascii" ) == 0 )
92 {
93 m_fileVersion = WRLVERSION::VRML_V1;
94 // nothing < 0x20, and no:
95 // single or double quote
96 // backslash
97 // curly brace
98 // plus
99 // period
100 m_badchars = "\"'\\{}+.";
101 return;
102 }
103
104 if( m_buf.compare( 0, 15, "#VRML V2.0 utf8" ) == 0 )
105 {
106 m_fileVersion = WRLVERSION::VRML_V2;
107 // nothing < 0x20, and no:
108 // single or double quotes
109 // sharp (#)
110 // plus
111 // minus
112 // comma
113 // period
114 // square brackets []
115 // curly braces {}
116 // backslash
117 // NOTE: badchars should include '-' but due to my bad model naming scheme
118 // in the VRML model generator, I have allowed '-'. Other VRML parsers seem to
119 // accept '-'. FreeCAD produces names with '+' in them so '+' has been allowed
120 // as well; '+' is not even valid for VRML1.
121 //m_badchars = "'\"#,.+-[]\\{}";
122 m_badchars = "'\"#,.[]\\{}";
123 return;
124 }
125
126 m_buf.clear();
127 m_fileVersion = WRLVERSION::VRML_INVALID;
128 m_eof = true;
129
130 m_error = "not a valid VRML file: '";
131 m_error.append( m_filename );
132 m_error.append( 1, '\'' );
133 m_badchars.clear();
134}
135
136
138{
139}
140
141
143{
144 m_error.clear();
145
146 if( !m_file )
147 {
148 m_error = "no open file";
149 return false;
150 }
151
152 if( m_bufpos >= m_buf.size() )
153 m_buf.clear();
154
155 if( !m_buf.empty() )
156 return true;
157
158 if( m_eof )
159 return false;
160
161 GETLINE;
162
163 if( m_eof && m_buf.empty() )
164 return false;
165
166 // strip the EOL characters
167 while( !m_buf.empty() && ( *m_buf.rbegin() == '\r' || *m_buf.rbegin() == '\n' ) )
168 m_buf.erase( --m_buf.end() );
169
170 if( WRLVERSION::VRML_V1 == m_fileVersion && !m_buf.empty() )
171 {
172 std::string::iterator sS = m_buf.begin();
173 std::string::iterator eS = m_buf.end();
174
175 while( sS != eS )
176 {
177 if( ( ( *sS ) & 0x80 ) )
178 {
179 m_error = " non-ASCII character sequence in VRML1 file";
180 return false;
181 }
182
183 ++sS;
184 }
185 }
186
187 return true;
188}
189
190
192{
193 if( !m_file )
194 {
195 m_error = "no open file";
196 return false;
197 }
198
199 if( m_bufpos >= m_buf.size() )
200 m_buf.clear();
201
202RETRY:
203 while( m_buf.empty() && !m_eof )
204 getRawLine();
205
206 // buffer may be empty if we have reached EOF or encountered IO errors
207 if( m_buf.empty() )
208 return false;
209
210 // eliminate leading white space (including control characters and comments)
211 while( m_bufpos < m_buf.size() )
212 {
213 if( m_buf[m_bufpos] > 0x20 )
214 break;
215
216 ++m_bufpos;
217 }
218
219 if( m_bufpos == m_buf.size() || '#' == m_buf[m_bufpos] )
220 {
221 // lines consisting entirely of white space are not unusual
222 m_buf.clear();
223 goto RETRY;
224 }
225
226 return true;
227}
228
229
231{
232 return m_fileVersion;
233}
234
235
236const char* WRLPROC::GetParentDir( void )
237{
238 if( m_filedir.empty() )
239 return nullptr;
240
241 return m_filedir.c_str();
242}
243
244
245bool WRLPROC::ReadGlob( std::string& aGlob )
246{
247 aGlob.clear();
248
249 if( !m_file )
250 {
251 m_error = "no open file";
252 return false;
253 }
254
255 while( true )
256 {
257 if( !EatSpace() )
258 return false;
259
260 // if the text is the start of a comment block, clear the buffer and loop
261 if( '#' == m_buf[m_bufpos] )
262 m_buf.clear();
263 else
264 break;
265 }
266
267 size_t ssize = m_buf.size();
268
269 while( m_bufpos < ssize && m_buf[m_bufpos] > 0x20 )
270 {
271 if( ',' == m_buf[m_bufpos] )
272 {
273 // the comma is a special instance of blank space
274 ++m_bufpos;
275 return true;
276 }
277
278 if( '{' == m_buf[m_bufpos] || '}' == m_buf[m_bufpos]
279 || '[' == m_buf[m_bufpos] || ']' == m_buf[m_bufpos] )
280 return true;
281
282 aGlob.append( 1, m_buf[m_bufpos++] );
283 }
284
285 return true;
286}
287
288
289bool WRLPROC::ReadName( std::string& aName )
290{
291 aName.clear();
292
293 if( !m_file )
294 {
295 m_error = "no open file";
296 return false;
297 }
298
299 while( true )
300 {
301 if( !EatSpace() )
302 return false;
303
304 // if the text is the start of a comment block, clear the buffer and loop
305 if( '#' == m_buf[m_bufpos] )
306 m_buf.clear();
307 else
308 break;
309 }
310
311 size_t ssize = m_buf.size();
312
313 while( m_bufpos < ssize && m_buf[m_bufpos] > 0x20 )
314 {
315 if( '[' == m_buf[m_bufpos] || '{' == m_buf[m_bufpos]
316 || ']' == m_buf[m_bufpos] || '}' == m_buf[m_bufpos]
317 || '.' == m_buf[m_bufpos] || '#' == m_buf[m_bufpos]
318 || ',' == m_buf[m_bufpos] )
319 {
320 if( !aName.empty() )
321 {
322 return true;
323 }
324 else
325 {
326 std::ostringstream ostr;
327 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
328 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
329 ostr << " * [INFO] line " << m_fileline << ", column " << m_bufpos;
330 ostr << " -- invalid name";
331 m_error = ostr.str();
332
333 return false;
334 }
335 }
336
337 if( m_badchars.find( m_buf[m_bufpos] ) != std::string::npos )
338 {
339 std::ostringstream ostr;
340 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
341 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
342 ostr << " * [INFO] line " << m_fileline << ", column " << m_bufpos;
343 ostr << " -- invalid character in name";
344 m_error = ostr.str();
345
346 return false;
347 }
348
349 if( aName.empty() && m_buf[m_bufpos] >= '0' && m_buf[m_bufpos] <= '9' )
350 {
351 std::ostringstream ostr;
352 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
353 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
354 ostr << " * [INFO] line " << m_fileline << ", column " << m_bufpos;
355 ostr << " -- name must not start with a digit";
356 m_error = ostr.str();
357
358 return false;
359 }
360
361 aName.append( 1, m_buf[m_bufpos++] );
362 }
363
364 return true;
365}
366
367
369{
370 if( !m_file )
371 {
372 m_error = "no open file";
373 return false;
374 }
375
376 if( !EatSpace() )
377 {
378 std::ostringstream ostr;
379 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
380 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
381 ostr << " * [INFO] " << m_error;
382 m_error = ostr.str();
383
384 return false;
385 }
386
387 if( '{' != m_buf[m_bufpos] )
388 {
389 std::ostringstream ostr;
390 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
391 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
392 ostr << " * [INFO] expecting character '{' at line " << m_fileline;
393 ostr << ", column " << m_bufpos;
394 m_error = ostr.str();
395
396 wxLogTrace( traceVrmlPlugin, "%s\n", m_error.c_str() );
397
398 return false;
399 }
400
401 size_t fileline = m_fileline;
402 size_t linepos = m_bufpos;
403
404 ++m_bufpos;
405 size_t lvl = 1;
406 std::string tmp;
407
408 while( lvl > 0 )
409 {
410 if( !EatSpace() )
411 {
412 std::ostringstream ostr;
413 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
414 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
415 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
416 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
417 ostr << " * [INFO] " << m_error;
418 m_error = ostr.str();
419
420 return false;
421 }
422
423 // comments must be skipped
424 if( '#' == m_buf[m_bufpos] )
425 {
426 m_bufpos = 0;
427 m_buf.clear();
428 continue;
429 }
430
431 if( '{' == m_buf[m_bufpos] )
432 {
433 ++m_bufpos;
434 ++lvl;
435 continue;
436 }
437
438 if( '}' == m_buf[m_bufpos] )
439 {
440 ++m_bufpos;
441 --lvl;
442 continue;
443 }
444
445 // note: if we have a ']' we must skip it and test the next non-blank character;
446 // this ensures that we don't miss a '}' in cases where the braces are not
447 // separated by space. if we had proceeded to ReadGlob() we could have had a problem.
448 if( ']' == m_buf[m_bufpos] || '[' == m_buf[m_bufpos] )
449 {
450 ++m_bufpos;
451 continue;
452 }
453
454 // strings are handled as a special case since they may contain
455 // control characters and braces
456 if( '"' == m_buf[m_bufpos] )
457 {
458 if( !ReadString( tmp ) )
459 {
460 std::ostringstream ostr;
461 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
462 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
463 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
464 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
465 ostr << " * [INFO] " << m_error;
466 m_error = ostr.str();
467
468 return false;
469 }
470 }
471
472 // everything at this point can be read and discarded via ReadGlob()
473 if( !ReadGlob( tmp ) )
474 {
475 std::ostringstream ostr;
476 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
477 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
478 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
479 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
480 ostr << " * [INFO] " << m_error;
481 m_error = ostr.str();
482
483 return false;
484 }
485 }
486
487 return true;
488}
489
490
492{
493 if( !m_file )
494 {
495 m_error = "no open file";
496 return false;
497 }
498
499 if( !EatSpace() )
500 {
501 std::ostringstream ostr;
502 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
503 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
504 ostr << " * [INFO] " << m_error;
505 m_error = ostr.str();
506
507 return false;
508 }
509
510 if( '[' != m_buf[m_bufpos] )
511 {
512 std::ostringstream ostr;
513 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
514 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
515 ostr << " * [INFO] expecting character '[' at line " << m_fileline;
516 ostr << ", column " << m_bufpos;
517 m_error = ostr.str();
518
519 return false;
520 }
521
522 size_t fileline = m_fileline;
523 size_t linepos = m_bufpos;
524
525 ++m_bufpos;
526 size_t lvl = 1;
527 std::string tmp;
528
529 while( lvl > 0 )
530 {
531 if( !EatSpace() )
532 {
533 std::ostringstream ostr;
534 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
535 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
536 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
537 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
538 ostr << " * [INFO] " << m_error;
539 m_error = ostr.str();
540
541 return false;
542 }
543
544 // comments must be skipped
545 if( '#' == m_buf[m_bufpos] )
546 {
547 m_bufpos = 0;
548 m_buf.clear();
549 continue;
550 }
551
552 if( '[' == m_buf[m_bufpos] )
553 {
554 ++m_bufpos;
555 ++lvl;
556 continue;
557 }
558
559 if( ']' == m_buf[m_bufpos] )
560 {
561 ++m_bufpos;
562 --lvl;
563 continue;
564 }
565
566 // note: if we have a '}' we must skip it and test the next non-blank character;
567 // this ensures that we don't miss a ']' in cases where the braces are not
568 // separated by space. if we had proceeded to ReadGlob() we could have had a problem.
569 if( '}' == m_buf[m_bufpos] || '{' == m_buf[m_bufpos] )
570 {
571 ++m_bufpos;
572 continue;
573 }
574
575 // strings are handled as a special case since they may contain
576 // control characters and braces
577 if( '"' == m_buf[m_bufpos] )
578 {
579 if( !ReadString( tmp ) )
580 {
581 std::ostringstream ostr;
582 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
583 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
584 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
585 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
586 ostr << " * [INFO] " << m_error;
587 m_error = ostr.str();
588
589 return false;
590 }
591 }
592
593 // everything at this point can be read and discarded via ReadGlob()
594 if( !ReadGlob( tmp ) )
595 {
596 std::ostringstream ostr;
597 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
598 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
599 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
600 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
601 ostr << " * [INFO] " << m_error;
602 m_error = ostr.str();
603
604 return false;
605 }
606 }
607
608 return false;
609}
610
611
612bool WRLPROC::ReadString( std::string& aSFString )
613{
614 // In VRML1 a string may be unquoted provided there are no space characters
615 // In VRML2 all strings must be quoted
616 aSFString.clear();
617
618 if( !m_file )
619 {
620 m_error = "no open file";
621 return false;
622 }
623
624 // remember the line number in case of errors
625 size_t ifline = m_fileline;
626
627 while( true )
628 {
629 if( !EatSpace() )
630 {
631 std::ostringstream ostr;
632 ostr << "invalid VRML file; expecting string at line " << ifline <<
633 " but found nothing";
634 m_error = ostr.str();
635
636 return false;
637 }
638
639 // if the text is the start of a comment block, clear the buffer and loop
640 if( '#' == m_buf[m_bufpos] )
641 m_buf.clear();
642 else
643 break;
644 }
645
646 if( WRLVERSION::VRML_V2 == m_fileVersion && '"' != m_buf[m_bufpos] )
647 {
648 m_error = "invalid VRML2 file (string not quoted)";
649 return false;
650 }
651
652 ifline = m_fileline;
653
654 if( '"' != m_buf[m_bufpos] )
655 {
656 if( !ReadGlob( aSFString ) )
657 {
658 std::ostringstream ostr;
659 ostr << "invalid VRML1 file at lines " << ifline << "--" << m_fileline;
660
661 if( !m_error.empty() )
662 ostr << " : " << m_error;
663
664 m_error = ostr.str();
665
666 return false;
667 }
668
669 return true;
670 }
671
672 bool isesc = false; // true if an escape character was found
673
674 while( true )
675 {
676 ++m_bufpos;
677
678 if( m_bufpos >= m_buf.size() )
679 {
680 aSFString.append( 1, '\n' );
681
682 if( !getRawLine() )
683 {
684 std::ostringstream ostr;
685 ostr << "invalid VRML1 file at lines " << ifline << "--" << m_fileline;
686 ostr << "; could not find end of string\n";
687 m_error = ostr.str();
688
689 return false;
690 }
691 }
692
693 if( '\\' == m_buf[m_bufpos] )
694 {
695 if( isesc )
696 {
697 aSFString.append( 1, '\n' );
698 isesc = false;
699 }
700 else
701 {
702 isesc = true;
703 }
704
705 continue;
706 }
707 else if( '"' == m_buf[m_bufpos] )
708 {
709 if( isesc )
710 aSFString.append( 1, '"' );
711 else
712 break;
713 }
714 else
715 {
716 aSFString.append( 1, m_buf[m_bufpos] );
717 }
718
719 // ensure that the backslash escape cannot extend beyond the first character
720 isesc = false;
721 }
722
723 ++m_bufpos;
724
725 return true;
726}
727
728
729bool WRLPROC::ReadSFBool( bool& aSFBool )
730{
731 if( !EatSpace() )
732 return false;
733
734 size_t fileline = m_fileline;
735 size_t linepos = m_bufpos;
736 std::string tmp;
737
738 if( !ReadGlob( tmp ) )
739 return false;
740
741 if( !tmp.compare( "0" ) )
742 {
743 aSFBool = false;
744 }
745 else if( !tmp.compare( "1" ) )
746 {
747 aSFBool = true;
748 }
749 else if( !tmp.compare( "TRUE" ) )
750 {
751 aSFBool = true;
752 }
753 else if( !tmp.compare( "FALSE" ) )
754 {
755 aSFBool = false;
756 }
757 else
758 {
759 std::ostringstream ostr;
760 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
761 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
762 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
763 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
764 ostr << " * [INFO] expected one of 0, 1, TRUE, FALSE but got '" << tmp << "'\n";
765 m_error = ostr.str();
766
767 return false;
768 }
769
770 return true;
771}
772
773
775{
776 if( !m_file )
777 {
778 m_error = "no open file";
779 return false;
780 }
781
782 size_t fileline = m_fileline;
783 size_t linepos = m_bufpos;
784
785 if( !ReadSFVec3f( aSFColor ) )
786 return false;
787
788 if( aSFColor.x < 0.0 || aSFColor.x > 1.0 || aSFColor.y < 0.0 || aSFColor.y > 1.0
789 || aSFColor.z < 0.0 || aSFColor.z > 1.0 )
790 {
791 std::ostringstream ostr;
792 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
793 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
794 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
795 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
796 ostr << " * [INFO] invalid RGB value in color triplet";
797 m_error = ostr.str();
798
799 return false;
800 }
801
802 return true;
803}
804
805
806bool WRLPROC::ReadSFFloat( float& aSFFloat )
807{
808 if( !m_file )
809 {
810 m_error = "no open file";
811 return false;
812 }
813
814 aSFFloat = 0.0;
815
816 size_t fileline = m_fileline;
817 size_t linepos = m_bufpos;
818
819 while( true )
820 {
821 if( !EatSpace() )
822 return false;
823
824 // if the text is the start of a comment block, clear the buffer and loop
825 if( '#' == m_buf[m_bufpos] )
826 m_buf.clear();
827 else
828 break;
829 }
830
831 std::string tmp;
832
833 if( !ReadGlob( tmp ) )
834 {
835 std::ostringstream ostr;
836 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
837 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
838 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
839 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
840 ostr << " * [INFO] " << m_error;
841 m_error = ostr.str();
842
843 return false;
844 }
845
846 std::istringstream istr;
847 istr.str( tmp );
848 istr >> aSFFloat;
849
850 if( istr.fail() || !istr.eof() )
851 {
852 std::ostringstream ostr;
853 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
854 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
855 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
856 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
857 ostr << " * [INFO] invalid character in SFFloat";
858 m_error = ostr.str();
859
860 return false;
861 }
862
863 return true;
864}
865
866
867bool WRLPROC::ReadSFInt( int& aSFInt32 )
868{
869 if( !m_file )
870 {
871 m_error = "no open file";
872 return false;
873 }
874
875 aSFInt32 = 0;
876 size_t fileline = m_fileline;
877 size_t linepos = m_bufpos;
878
879 while( true )
880 {
881 if( !EatSpace() )
882 return false;
883
884 // if the text is the start of a comment block, clear the buffer and loop
885 if( '#' == m_buf[m_bufpos] )
886 m_buf.clear();
887 else
888 break;
889 }
890
891 std::string tmp;
892
893 if( !ReadGlob( tmp ) )
894 {
895 std::ostringstream ostr;
896 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
897 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
898 ostr << " * [INFO] line " << fileline<< ", char " << linepos << " -- ";
899 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
900 ostr << " * [INFO] " << m_error;
901 m_error = ostr.str();
902
903 return false;
904 }
905
906 if( std::string::npos != tmp.find( "0x" ) )
907 {
908 // Rules: "0x" + "0-9, A-F" - VRML is case sensitive but in
909 // this instance we do no enforce case.
910 std::stringstream sstr;
911 sstr << std::hex << tmp;
912 sstr >> aSFInt32;
913 return true;
914 }
915
916 std::istringstream istr;
917 istr.str( tmp );
918 istr >> aSFInt32;
919
920 if( istr.fail() || !istr.eof() )
921 {
922 std::ostringstream ostr;
923 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
924 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
925 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
926 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
927 ostr << " * [INFO] invalid character in SFInt";
928 m_error = ostr.str();
929
930 return false;
931 }
932
933 return true;
934}
935
936
938{
939 if( !m_file )
940 {
941 m_error = "no open file";
942 return false;
943 }
944
945 aSFRotation.x = 0.0;
946 aSFRotation.y = 0.0;
947 aSFRotation.z = 1.0;
948 aSFRotation.w = 0.0;
949
950 size_t fileline = m_fileline;
951 size_t linepos = m_bufpos;
952
953 while( true )
954 {
955 if( !EatSpace() )
956 return false;
957
958 // if the text is the start of a comment block, clear the buffer and loop
959 if( '#' == m_buf[m_bufpos] )
960 m_buf.clear();
961 else
962 break;
963 }
964
965 std::string tmp;
966 float trot[4];
967
968 for( int i = 0; i < 4; ++i )
969 {
970 if( !ReadGlob( tmp ) )
971 {
972 std::ostringstream ostr;
973 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
974 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
975 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
976 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
977 ostr << " * [INFO] " << m_error;
978 m_error = ostr.str();
979
980 return false;
981 }
982
983 std::istringstream istr;
984 istr.str( tmp );
985 istr >> trot[i];
986
987 if( istr.fail() || !istr.eof() )
988 {
989 std::ostringstream ostr;
990 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
991 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
992 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
993 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
994 ostr << " * [INFO] invalid character in space delimited quartet";
995 m_error = ostr.str();
996
997 return false;
998 }
999
1000 }
1001
1002 aSFRotation.x = trot[0];
1003 aSFRotation.y = trot[1];
1004 aSFRotation.z = trot[2];
1005 aSFRotation.w = trot[3];
1006
1007 return true;
1008}
1009
1010
1012{
1013 if( !m_file )
1014 {
1015 m_error = "no open file";
1016 return false;
1017 }
1018
1019 aSFVec2f.x = 0.0;
1020 aSFVec2f.y = 0.0;
1021
1022 size_t fileline = m_fileline;
1023 size_t linepos = m_bufpos;
1024
1025 while( true )
1026 {
1027 if( !EatSpace() )
1028 return false;
1029
1030 // if the text is the start of a comment block, clear the buffer and loop
1031 if( '#' == m_buf[m_bufpos] )
1032 m_buf.clear();
1033 else
1034 break;
1035 }
1036
1037 std::string tmp;
1038
1039 float tcol[2];
1040
1041 for( int i = 0; i < 2; ++i )
1042 {
1043 if( !ReadGlob( tmp ) )
1044 {
1045 std::ostringstream ostr;
1046 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1047 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1048 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1049 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1050 ostr << " * [INFO] " << m_error;
1051 m_error = ostr.str();
1052
1053 return false;
1054 }
1055
1056 std::istringstream istr;
1057 istr.str( tmp );
1058 istr >> tcol[i];
1059
1060 if( istr.fail() || !istr.eof() )
1061 {
1062 std::ostringstream ostr;
1063 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1064 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1065 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1066 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1067 ostr << " * [INFO] invalid character in space delimited pair";
1068 m_error = ostr.str();
1069
1070 return false;
1071 }
1072
1073 }
1074
1075 aSFVec2f.x = tcol[0];
1076 aSFVec2f.y = tcol[1];
1077
1078 return true;
1079}
1080
1081
1083{
1084 if( !m_file )
1085 {
1086 m_error = "no open file";
1087 return false;
1088 }
1089
1090 aSFVec3f.x = 0.0;
1091 aSFVec3f.y = 0.0;
1092 aSFVec3f.z = 0.0;
1093
1094 size_t fileline = m_fileline;
1095 size_t linepos = m_bufpos;
1096
1097 while( true )
1098 {
1099 if( !EatSpace() )
1100 return false;
1101
1102 // if the text is the start of a comment block, clear the buffer and loop
1103 if( '#' == m_buf[m_bufpos] )
1104 m_buf.clear();
1105 else
1106 break;
1107 }
1108
1109 std::string tmp;
1110
1111 float tcol[3];
1112
1113 for( int i = 0; i < 3; ++i )
1114 {
1115 if( !ReadGlob( tmp ) )
1116 {
1117 std::ostringstream ostr;
1118 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1119 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1120 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1121 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1122 ostr << " * [INFO] " << m_error;
1123 m_error = ostr.str();
1124
1125 return false;
1126 }
1127
1128 // ignore any commas
1129 if( !EatSpace() )
1130 return false;
1131
1132 if( ',' == m_buf[m_bufpos] )
1133 Pop();
1134
1135 std::istringstream istr;
1136 istr.str( tmp );
1137 istr >> tcol[i];
1138
1139 if( istr.fail() || !istr.eof() )
1140 {
1141 std::ostringstream ostr;
1142 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1143 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1144 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1145 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1146 ostr << " * [INFO] invalid character in space delimited triplet";
1147 m_error = ostr.str();
1148
1149 return false;
1150 }
1151
1152 }
1153
1154 aSFVec3f.x = tcol[0];
1155 aSFVec3f.y = tcol[1];
1156 aSFVec3f.z = tcol[2];
1157
1158 return true;
1159}
1160
1161
1162bool WRLPROC::ReadMFString( std::vector< std::string >& aMFString )
1163{
1164 aMFString.clear();
1165 size_t fileline = m_fileline;
1166 size_t linepos = m_bufpos;
1167
1168 if( !m_file )
1169 {
1170 m_error = "no open file";
1171 return false;
1172 }
1173
1174 while( true )
1175 {
1176 if( !EatSpace() )
1177 return false;
1178
1179 // if the text is the start of a comment block, clear the buffer and loop
1180 if( '#' == m_buf[m_bufpos] )
1181 m_buf.clear();
1182 else
1183 break;
1184 }
1185
1186 std::string lstr;
1187
1188 if( m_buf[m_bufpos] != '[' )
1189 {
1190 if( !ReadString( lstr ) )
1191 {
1192 std::ostringstream ostr;
1193 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1194 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1195 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1196 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1197 ostr << " * [INFO] " << m_error;
1198 m_error = ostr.str();
1199
1200 return false;
1201 }
1202
1203 if( m_bufpos >= m_buf.size() && !EatSpace() )
1204 {
1205 std::ostringstream ostr;
1206 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1207 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1208 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1209 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1210 ostr << " * [INFO] could not check characters after the string";
1211 m_error = ostr.str();
1212
1213 return false;
1214 }
1215
1216 if( ',' == m_buf[m_bufpos] )
1217 Pop();
1218
1219 aMFString.push_back( lstr );
1220 return true;
1221 }
1222
1223 ++m_bufpos;
1224
1225 while( true )
1226 {
1227 if( !ReadString( lstr ) )
1228 {
1229 std::ostringstream ostr;
1230 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1231 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1232 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1233 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1234 ostr << " * [INFO] " << m_error;
1235 m_error = ostr.str();
1236
1237 return false;
1238 }
1239
1240 if( !EatSpace() )
1241 {
1242 std::ostringstream ostr;
1243 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1244 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1245 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1246 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1247 ostr << " * [INFO] could not check characters after the string";
1248 m_error = ostr.str();
1249
1250 return false;
1251 }
1252
1253 if( ',' == m_buf[m_bufpos] )
1254 Pop();
1255
1256 aMFString.push_back( lstr );
1257
1258 if( !EatSpace() )
1259 {
1260 std::ostringstream ostr;
1261 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1262 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1263 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1264 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1265 ostr << " * [INFO] problems encountered while reading list";
1266 m_error = ostr.str();
1267
1268 return false;
1269 }
1270
1271 if( ']' == m_buf[m_bufpos] )
1272 break;
1273
1274 }
1275
1276 ++m_bufpos;
1277 return true;
1278}
1279
1280
1281bool WRLPROC::ReadMFColor( std::vector< WRLVEC3F >& aMFColor )
1282{
1283 aMFColor.clear();
1284 size_t fileline = m_fileline;
1285 size_t linepos = m_bufpos;
1286
1287 if( !m_file )
1288 {
1289 m_error = "no open file";
1290 return false;
1291 }
1292
1293 WRLVEC3F lcolor;
1294
1295 while( true )
1296 {
1297 if( !EatSpace() )
1298 return false;
1299
1300 // if the text is the start of a comment block, clear the buffer and loop
1301 if( '#' == m_buf[m_bufpos] )
1302 m_buf.clear();
1303 else
1304 break;
1305 }
1306
1307 if( m_buf[m_bufpos] != '[' )
1308 {
1309 if( !ReadSFColor( lcolor ) )
1310 {
1311 std::ostringstream ostr;
1312 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1313 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1314 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1315 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1316 ostr << " * [INFO] " << m_error;
1317 m_error = ostr.str();
1318
1319 return false;
1320 }
1321
1322 if( !EatSpace() )
1323 {
1324 std::ostringstream ostr;
1325 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1326 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1327 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1328 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1329 ostr << " * [INFO] could not check characters after the string";
1330 m_error = ostr.str();
1331
1332 return false;
1333 }
1334
1335 if( ',' == m_buf[m_bufpos] )
1336 Pop();
1337
1338 aMFColor.push_back( lcolor );
1339 return true;
1340 }
1341
1342 ++m_bufpos;
1343
1344 while( true )
1345 {
1346 if( !EatSpace() )
1347 return false;
1348
1349 if( ']' == m_buf[m_bufpos] )
1350 break;
1351
1352 if( !ReadSFColor( lcolor ) )
1353 {
1354 std::ostringstream ostr;
1355 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1356 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1357 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1358 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1359 ostr << " * [INFO] " << m_error;
1360 m_error = ostr.str();
1361
1362 return false;
1363 }
1364
1365 aMFColor.push_back( lcolor );
1366
1367 if( !EatSpace() )
1368 {
1369 std::ostringstream ostr;
1370 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1371 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1372 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1373 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1374 ostr << " * [INFO] could not check characters after the string";
1375 m_error = ostr.str();
1376
1377 return false;
1378 }
1379
1380 if( ']' == m_buf[m_bufpos] )
1381 break;
1382
1383 if( ',' == m_buf[m_bufpos] )
1384 Pop();
1385
1386 }
1387
1388 ++m_bufpos;
1389 return true;
1390}
1391
1392
1393bool WRLPROC::ReadMFFloat( std::vector< float >& aMFFloat )
1394{
1395 aMFFloat.clear();
1396 size_t fileline = m_fileline;
1397 size_t linepos = m_bufpos;
1398
1399 if( !m_file )
1400 {
1401 m_error = "no open file";
1402 return false;
1403 }
1404
1405 float temp;
1406
1407 while( true )
1408 {
1409 if( !EatSpace() )
1410 return false;
1411
1412 // if the text is the start of a comment block, clear the buffer and loop
1413 if( '#' == m_buf[m_bufpos] )
1414 m_buf.clear();
1415 else
1416 break;
1417 }
1418
1419 if( m_buf[m_bufpos] != '[' )
1420 {
1421 if( !ReadSFFloat( temp ) )
1422 {
1423 std::ostringstream ostr;
1424 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1425 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1426 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1427 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1428 ostr << " * [INFO] " << m_error;
1429 m_error = ostr.str();
1430
1431 return false;
1432 }
1433
1434 if( !EatSpace() )
1435 {
1436 std::ostringstream ostr;
1437 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1438 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1439 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1440 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1441 ostr << " * [INFO] could not check characters after the string";
1442 m_error = ostr.str();
1443
1444 return false;
1445 }
1446
1447 if( ',' == m_buf[m_bufpos] )
1448 Pop();
1449
1450 aMFFloat.push_back( temp );
1451 return true;
1452 }
1453
1454 ++m_bufpos;
1455
1456 while( true )
1457 {
1458 if( !EatSpace() )
1459 return false;
1460
1461 if( ']' == m_buf[m_bufpos] )
1462 break;
1463
1464 if( !ReadSFFloat( temp ) )
1465 {
1466 std::ostringstream ostr;
1467 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1468 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1469 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1470 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1471 ostr << " * [INFO] " << m_error;
1472 m_error = ostr.str();
1473
1474 return false;
1475 }
1476
1477 aMFFloat.push_back( temp );
1478
1479 if( !EatSpace() )
1480 {
1481 std::ostringstream ostr;
1482 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1483 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1484 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1485 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1486 ostr << " * [INFO] could not check characters after the string";
1487 m_error = ostr.str();
1488
1489 return false;
1490 }
1491
1492 if( ']' == m_buf[m_bufpos] )
1493 break;
1494
1495 if( ',' == m_buf[m_bufpos] )
1496 Pop();
1497 }
1498
1499 ++m_bufpos;
1500 return true;
1501}
1502
1503
1504bool WRLPROC::ReadMFInt( std::vector< int >& aMFInt32 )
1505{
1506 aMFInt32.clear();
1507 size_t fileline = m_fileline;
1508 size_t linepos = m_bufpos;
1509
1510 if( !m_file )
1511 {
1512 m_error = "no open file";
1513 return false;
1514 }
1515
1516 int temp;
1517
1518 while( true )
1519 {
1520 if( !EatSpace() )
1521 return false;
1522
1523 // if the text is the start of a comment block, clear the buffer and loop
1524 if( '#' == m_buf[m_bufpos] )
1525 m_buf.clear();
1526 else
1527 break;
1528 }
1529
1530 if( m_buf[m_bufpos] != '[' )
1531 {
1532 if( !ReadSFInt( temp ) )
1533 {
1534 std::ostringstream ostr;
1535 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1536 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1537 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1538 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1539 ostr << " * [INFO] " << m_error;
1540 m_error = ostr.str();
1541
1542 return false;
1543 }
1544
1545 if( !EatSpace() )
1546 {
1547 std::ostringstream ostr;
1548 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1549 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1550 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1551 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1552 ostr << " * [INFO] could not check characters after the string";
1553 m_error = ostr.str();
1554
1555 return false;
1556 }
1557
1558 if( ',' == m_buf[m_bufpos] )
1559 Pop();
1560
1561 aMFInt32.push_back( temp );
1562 return true;
1563 }
1564
1565 ++m_bufpos;
1566
1567 while( true )
1568 {
1569 if( !EatSpace() )
1570 return false;
1571
1572 if( ']' == m_buf[m_bufpos] )
1573 break;
1574
1575 if( !ReadSFInt( temp ) )
1576 {
1577 std::ostringstream ostr;
1578 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1579 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1580 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1581 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1582 ostr << " * [INFO] " << m_error;
1583 m_error = ostr.str();
1584
1585 return false;
1586 }
1587
1588 aMFInt32.push_back( temp );
1589
1590 if( !EatSpace() )
1591 {
1592 std::ostringstream ostr;
1593 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1594 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1595 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1596 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1597 ostr << " * [INFO] could not check characters after the string";
1598 m_error = ostr.str();
1599
1600 return false;
1601 }
1602
1603 if( ']' == m_buf[m_bufpos] )
1604 break;
1605
1606 if( ',' == m_buf[m_bufpos] )
1607 Pop();
1608
1609 }
1610
1611 ++m_bufpos;
1612 return true;
1613}
1614
1615
1616bool WRLPROC::ReadMFRotation( std::vector< WRLROTATION >& aMFRotation )
1617{
1618 aMFRotation.clear();
1619 size_t fileline = m_fileline;
1620 size_t linepos = m_bufpos;
1621
1622 if( !m_file )
1623 {
1624 m_error = "no open file";
1625 return false;
1626 }
1627
1628 WRLROTATION lrot;
1629
1630 while( true )
1631 {
1632 if( !EatSpace() )
1633 return false;
1634
1635 // if the text is the start of a comment block, clear the buffer and loop
1636 if( '#' == m_buf[m_bufpos] )
1637 m_buf.clear();
1638 else
1639 break;
1640 }
1641
1642 if( m_buf[m_bufpos] != '[' )
1643 {
1644 if( !ReadSFRotation( lrot ) )
1645 {
1646 std::ostringstream ostr;
1647 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1648 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1649 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1650 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1651 ostr << " * [INFO] " << m_error;
1652 m_error = ostr.str();
1653
1654 return false;
1655 }
1656
1657 if( !EatSpace() )
1658 {
1659 std::ostringstream ostr;
1660 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1661 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1662 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1663 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1664 ostr << " * [INFO] could not check characters after the string";
1665 m_error = ostr.str();
1666
1667 return false;
1668 }
1669
1670 if( ',' == m_buf[m_bufpos] )
1671 Pop();
1672
1673 aMFRotation.push_back( lrot );
1674 return true;
1675 }
1676
1677 ++m_bufpos;
1678
1679 while( true )
1680 {
1681 if( !EatSpace() )
1682 return false;
1683
1684 if( ']' == m_buf[m_bufpos] )
1685 break;
1686
1687 if( !ReadSFRotation( lrot ) )
1688 {
1689 std::ostringstream ostr;
1690 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1691 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1692 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1693 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1694 ostr << " * [INFO] " << m_error;
1695 m_error = ostr.str();
1696
1697 return false;
1698 }
1699
1700 aMFRotation.push_back( lrot );
1701
1702 if( !EatSpace() )
1703 {
1704 std::ostringstream ostr;
1705 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1706 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1707 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1708 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1709 ostr << " * [INFO] could not check characters after the string";
1710 m_error = ostr.str();
1711
1712 return false;
1713 }
1714
1715 if( ']' == m_buf[m_bufpos] )
1716 break;
1717
1718 if( ',' == m_buf[m_bufpos] )
1719 Pop();
1720
1721 }
1722
1723 ++m_bufpos;
1724 return true;
1725}
1726
1727
1728bool WRLPROC::ReadMFVec2f( std::vector< WRLVEC2F >& aMFVec2f )
1729{
1730 aMFVec2f.clear();
1731 size_t fileline = m_fileline;
1732 size_t linepos = m_bufpos;
1733
1734 if( !m_file )
1735 {
1736 m_error = "no open file";
1737 return false;
1738 }
1739
1740 WRLVEC2F lvec2f;
1741
1742 while( true )
1743 {
1744 if( !EatSpace() )
1745 return false;
1746
1747 // if the text is the start of a comment block, clear the buffer and loop
1748 if( '#' == m_buf[m_bufpos] )
1749 m_buf.clear();
1750 else
1751 break;
1752 }
1753
1754 if( m_buf[m_bufpos] != '[' )
1755 {
1756 if( !ReadSFVec2f( lvec2f ) )
1757 {
1758 std::ostringstream ostr;
1759 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1760 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1761 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1762 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1763 ostr << " * [INFO] " << m_error;
1764 m_error = ostr.str();
1765
1766 return false;
1767 }
1768
1769 if( !EatSpace() )
1770 {
1771 std::ostringstream ostr;
1772 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1773 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1774 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1775 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1776 ostr << " * [INFO] could not check characters after the string";
1777 m_error = ostr.str();
1778
1779 return false;
1780 }
1781
1782 if( ',' == m_buf[m_bufpos] )
1783 Pop();
1784
1785 aMFVec2f.push_back( lvec2f );
1786 return true;
1787 }
1788
1789 ++m_bufpos;
1790
1791 while( true )
1792 {
1793 if( !EatSpace() )
1794 return false;
1795
1796 if( ']' == m_buf[m_bufpos] )
1797 break;
1798
1799 if( !ReadSFVec2f( lvec2f ) )
1800 {
1801 std::ostringstream ostr;
1802 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1803 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1804 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1805 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1806 ostr << " * [INFO] " << m_error;
1807 m_error = ostr.str();
1808
1809 return false;
1810 }
1811
1812 aMFVec2f.push_back( lvec2f );
1813
1814 if( !EatSpace() )
1815 {
1816 std::ostringstream ostr;
1817 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1818 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1819 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1820 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1821 ostr << " * [INFO] could not check characters after the string";
1822 m_error = ostr.str();
1823
1824 return false;
1825 }
1826
1827 if( ']' == m_buf[m_bufpos] )
1828 break;
1829
1830 if( ',' == m_buf[m_bufpos] )
1831 Pop();
1832 }
1833
1834 ++m_bufpos;
1835 return true;
1836}
1837
1838
1839bool WRLPROC::ReadMFVec3f( std::vector< WRLVEC3F >& aMFVec3f )
1840{
1841 aMFVec3f.clear();
1842 size_t fileline = m_fileline;
1843 size_t linepos = m_bufpos;
1844
1845 if( !m_file )
1846 {
1847 m_error = "no open file";
1848 return false;
1849 }
1850
1851 WRLVEC3F lvec3f;
1852
1853 while( true )
1854 {
1855 if( !EatSpace() )
1856 return false;
1857
1858 // if the text is the start of a comment block, clear the buffer and loop
1859 if( '#' == m_buf[m_bufpos] )
1860 m_buf.clear();
1861 else
1862 break;
1863 }
1864
1865 if( m_buf[m_bufpos] != '[' )
1866 {
1867 if( !ReadSFVec3f( lvec3f ) )
1868 {
1869 std::ostringstream ostr;
1870 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1871 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1872 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1873 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1874 ostr << " * [INFO] " << m_error;
1875 m_error = ostr.str();
1876
1877 return false;
1878 }
1879
1880 if( !EatSpace() )
1881 {
1882 std::ostringstream ostr;
1883 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1884 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1885 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1886 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1887 ostr << " * [INFO] could not check characters after the string";
1888 m_error = ostr.str();
1889
1890 return false;
1891 }
1892
1893 if( ',' == m_buf[m_bufpos] )
1894 Pop();
1895
1896 aMFVec3f.push_back( lvec3f );
1897 return true;
1898 }
1899
1900 ++m_bufpos;
1901
1902 while( true )
1903 {
1904 if( !EatSpace() )
1905 return false;
1906
1907 if( ']' == m_buf[m_bufpos] )
1908 break;
1909
1910 if( !ReadSFVec3f( lvec3f ) )
1911 {
1912 std::ostringstream ostr;
1913 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1914 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1915 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1916 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1917 ostr << " * [INFO] " << m_error;
1918 m_error = ostr.str();
1919
1920 return false;
1921 }
1922
1923 aMFVec3f.push_back( lvec3f );
1924
1925 if( !EatSpace() )
1926 {
1927 std::ostringstream ostr;
1928 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
1929 ostr << " * [INFO] failed on file '" << m_filename << "'\n";
1930 ostr << " * [INFO] line " << fileline << ", char " << linepos << " -- ";
1931 ostr << "line " << m_fileline << ", char " << m_bufpos << "\n";
1932 ostr << " * [INFO] could not check characters after the string";
1933 m_error = ostr.str();
1934
1935 return false;
1936 }
1937
1938 if( !EatSpace() )
1939 return false;
1940
1941 if( ']' == m_buf[m_bufpos] )
1942 break;
1943
1944 if( ',' == m_buf[m_bufpos] )
1945 Pop();
1946
1947 }
1948
1949 ++m_bufpos;
1950 return true;
1951}
1952
1953
1954bool WRLPROC::eof( void )
1955{
1956 return m_eof;
1957}
1958
1959
1960std::string WRLPROC::GetError( void )
1961{
1962 return m_error;
1963}
1964
1965
1966bool WRLPROC::GetFilePosData( size_t& line, size_t& column )
1967{
1968 if( !m_file )
1969 {
1970 line = 0;
1971 column = 0;
1972 return false;
1973 }
1974
1975 line = m_fileline;
1976 column = m_bufpos;
1977
1978 return true;
1979}
1980
1981
1982std::string WRLPROC::GetFilePosition() const
1983{
1984 std::ostringstream retv;
1985
1986 if( !m_file )
1987 retv << "no file loaded to provide file position information";
1988 else
1989 retv << "at line " << m_fileline << ", column " << m_bufpos;
1990
1991 return retv.str();
1992}
1993
1994
1995std::string WRLPROC::GetFileName( void )
1996{
1997 if( !m_file )
1998 {
1999 m_error = "no open file";
2000 return "";
2001 }
2002
2003 return std::string( m_file->GetSource().ToUTF8() );
2004}
2005
2006
2007char WRLPROC::Peek( void )
2008{
2009 if( !m_file )
2010 {
2011 std::ostringstream ostr;
2012 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
2013 ostr << " * [BUG] no open file";
2014 m_error = ostr.str();
2015 return '\0';
2016 }
2017
2018 if( !EatSpace() )
2019 {
2020 if( m_error.empty() )
2021 {
2022 std::ostringstream ostr;
2023 ostr << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "\n";
2024 ostr << " * [INFO] failed to read data from file\n";
2025 m_error = ostr.str();
2026 }
2027
2028 return '\0';
2029 }
2030
2031 return m_buf[m_bufpos];
2032}
2033
2034
2035void WRLPROC::Pop( void )
2036{
2037 if( m_bufpos < m_buf.size() )
2038 ++m_bufpos;
2039}
An abstract class from which implementation specific LINE_READERs may be derived to read single lines...
Definition: richio.h:93
virtual const wxString & GetSource() const
Returns the name of the source of the lines in an abstract sense.
Definition: richio.h:121
WRLVERSION m_fileVersion
Definition: wrlproc.h:114
bool DiscardList(void)
Definition: wrlproc.cpp:491
bool ReadGlob(std::string &aGlob)
Definition: wrlproc.cpp:245
bool ReadSFInt(int &aSFInt32)
Definition: wrlproc.cpp:867
bool ReadMFString(std::vector< std::string > &aMFString)
Definition: wrlproc.cpp:1162
bool ReadString(std::string &aSFString)
Definition: wrlproc.cpp:612
unsigned int m_fileline
Definition: wrlproc.h:111
std::string m_error
Definition: wrlproc.h:115
void Pop(void)
Definition: wrlproc.cpp:2035
bool ReadSFFloat(float &aSFFloat)
Definition: wrlproc.cpp:806
char Peek(void)
Definition: wrlproc.cpp:2007
std::string GetFileName(void)
Definition: wrlproc.cpp:1995
bool EatSpace(void)
Definition: wrlproc.cpp:191
bool ReadSFColor(WRLVEC3F &aSFColor)
Definition: wrlproc.cpp:774
bool ReadSFVec2f(WRLVEC2F &aSFVec2f)
Definition: wrlproc.cpp:1011
WRLVERSION GetVRMLType(void)
Definition: wrlproc.cpp:230
bool ReadMFInt(std::vector< int > &aMFInt32)
Definition: wrlproc.cpp:1504
std::string m_filename
Definition: wrlproc.h:117
const char * GetParentDir(void)
Definition: wrlproc.cpp:236
bool ReadMFFloat(std::vector< float > &aMFFloat)
Definition: wrlproc.cpp:1393
bool GetFilePosData(size_t &line, size_t &column)
Definition: wrlproc.cpp:1966
bool getRawLine(void)
Definition: wrlproc.cpp:142
std::string GetError(void)
Definition: wrlproc.cpp:1960
bool ReadMFVec2f(std::vector< WRLVEC2F > &aMFVec2f)
Definition: wrlproc.cpp:1728
std::string m_badchars
Definition: wrlproc.h:116
bool ReadSFBool(bool &aSFBool)
Definition: wrlproc.cpp:729
std::string m_filedir
Definition: wrlproc.h:118
LINE_READER * m_file
Definition: wrlproc.h:108
unsigned int m_bufpos
Definition: wrlproc.h:112
bool eof(void)
Definition: wrlproc.cpp:1954
bool ReadMFRotation(std::vector< WRLROTATION > &aMFRotation)
Definition: wrlproc.cpp:1616
bool ReadMFVec3f(std::vector< WRLVEC3F > &aMFVec3f)
Definition: wrlproc.cpp:1839
bool ReadName(std::string &aName)
Definition: wrlproc.cpp:289
bool m_eof
Definition: wrlproc.h:110
std::string GetFilePosition() const
Definition: wrlproc.cpp:1982
bool DiscardNode(void)
Definition: wrlproc.cpp:368
bool ReadMFColor(std::vector< WRLVEC3F > &aMFColor)
Definition: wrlproc.cpp:1281
~WRLPROC()
Definition: wrlproc.cpp:137
std::string m_buf
Definition: wrlproc.h:109
bool ReadSFRotation(WRLROTATION &aSFRotation)
Definition: wrlproc.cpp:937
WRLPROC(LINE_READER *aLineReader)
Definition: wrlproc.cpp:61
bool ReadSFVec3f(WRLVEC3F &aSFVec3f)
Definition: wrlproc.cpp:1082
const wxChar *const traceVrmlPlugin
Flag to enable VRML plugin trace output.
Definition: vrml.cpp:63
#define GETLINE
Definition: wrlproc.cpp:32
defines the basic input class for VRML
WRLVERSION
Definition: wrltypes.h:44
glm::vec4 WRLROTATION
Definition: wrltypes.h:189
glm::vec2 WRLVEC2F
Definition: wrltypes.h:187
glm::vec3 WRLVEC3F
Definition: wrltypes.h:188
#define FN_NORMALIZE_FLAGS
Default flags to pass to wxFileName::Normalize().
Definition: wx_filename.h:39