1 /*
2     Copyright (c) 2008-2009 NetAllied Systems GmbH
3 
4     This file is part of GeneratedSaxParser.
5 
6     Licensed under the MIT Open Source License,
7     for details please see LICENSE file or the website
8     http://www.opensource.org/licenses/mit-license.php
9 */
10 
11 #include "GeneratedSaxParserUtils.h"
12 #include <cmath>
13 #include <memory>
14 #include <string.h>
15 #include <limits>
16 #include <algorithm>
17 
18 namespace GeneratedSaxParser
19 {
20 
21 	//--------------------------------------------------------------------
calculateStringHash(const ParserChar * text,size_t textLength)22 	StringHash Utils::calculateStringHash( const ParserChar* text, size_t textLength )
23 	{
24 		StringHash h = 0;
25 		StringHash g;
26 
27 		while (textLength--) {
28 			h = (h << 4) + *text++;
29 			if ((g = (h & 0xf0000000)) != 0)
30 				h ^= g >> 24;
31 			h &= ~g;
32 		}
33 		return h;
34 	}
35 
36     //--------------------------------------------------------------------
calculateStringHash(const ParserChar ** text,const ParserChar * bufferEnd,bool & failed)37     StringHash Utils::calculateStringHash( const ParserChar** text, const ParserChar* bufferEnd, bool& failed )
38     {
39         failed = false;
40         StringHash h = 0;
41         StringHash g;
42         const ParserChar* bufferPos = *text;
43 
44         if ( !bufferPos )
45         {
46             failed = true;
47             *text = bufferPos;
48             return 0;
49         }
50 
51         if ( bufferPos == bufferEnd )
52         {
53             failed = true;
54             *text = bufferPos;
55             return 0;
56         }
57         // Skip leading white spaces
58         while ( isWhiteSpace(*bufferPos) )
59         {
60             ++bufferPos;
61             if ( bufferPos == bufferEnd )
62             {
63                 failed = true;
64                 *text = bufferPos;
65                 return 0;
66             }
67         }
68 
69         while ( bufferPos != bufferEnd ) {
70             if ( isWhiteSpace(*bufferPos) )
71             {
72                 *text = bufferPos;
73                 return h;
74             }
75             h = (h << 4) + *bufferPos++;
76             if ((g = (h & 0xf0000000)) != 0)
77                 h ^= g >> 24;
78             h &= ~g;
79         }
80         *text = bufferPos;
81         return h;
82     }
83 
84 	//--------------------------------------------------------------------
calculateStringHash(StringHash prefixHash,const char * separator,const ParserChar * text)85 	StringHash Utils::calculateStringHash( StringHash prefixHash, const char* separator, const ParserChar* text )
86 	{
87 		StringHash h = prefixHash;
88 		StringHash g;
89 		const char* separatorPos = separator;
90 
91 		while (*separatorPos != 0) {
92 			h = (h << 4) + *separatorPos++;
93 			if ((g = (h & 0xf0000000)) != 0)
94 				h ^= g >> 24;
95 			h &= ~g;
96 		}
97 
98 		const ParserChar* textPos = text;
99 		while (*textPos != 0) {
100 			h = (h << 4) + *textPos++;
101 			if ((g = (h & 0xf0000000)) != 0)
102 				h ^= g >> 24;
103 			h &= ~g;
104 		}
105 		return h;
106 	}
107 
108 
109 	//--------------------------------------------------------------------
calculateStringHash(const ParserChar * text)110 	StringHash Utils::calculateStringHash( const ParserChar* text )
111 	{
112 		StringHash h = 0;
113 		StringHash g;
114 		const ParserChar* pos = text;
115 
116 		while (*pos != 0) {
117 			h = (h << 4) + *pos++;
118 			if ((g = (h & 0xf0000000)) != 0)
119 				h ^= g >> 24;
120 			h &= ~g;
121 		}
122 		return h;
123 	}
124 
125     //--------------------------------------------------------------------
calculateStringHashWithNamespace(const ParserChar * text)126     StringHashPair Utils::calculateStringHashWithNamespace( const ParserChar* text )
127     {
128         StringHash h = 0;
129         StringHash g;
130         const ParserChar* pos = text;
131         StringHashPair pair;
132         pair.first = 0;
133 
134         while (*pos != 0) {
135             if (*pos == ':' && pos[1] != 0) {
136                 pair.first = h;
137                 h = 0;
138                 pos++;
139             }
140             h = (h << 4) + *pos++;
141             if ((g = (h & 0xf0000000)) != 0)
142                 h ^= g >> 24;
143             h &= ~g;
144         }
145         pair.second = h;
146         return pair;
147     }
148 
149     //--------------------------------------------------------------------
calculateStringHash(const ParserChar * text,bool & failed)150 	GeneratedSaxParser::StringHash Utils::calculateStringHash( const ParserChar* text, bool& failed )
151 	{
152 		failed = false;
153 		return calculateStringHash(text);
154 	}
155 
156 
157     //--------------------------------------------------------------------
isWhiteSpaceOnly(const ParserChar * buffer,size_t length)158     bool Utils::isWhiteSpaceOnly(const ParserChar* buffer, size_t length)
159     {
160         for (size_t i=0; i<length; ++i)
161         {
162             if ( !isWhiteSpace(buffer[i]) )
163             {
164                 return false;
165             }
166         }
167         return true;
168     }
169 
170     //--------------------------------------------------------------------
fillErrorMsg(ParserChar * dest,const ParserChar * src,size_t maxLen)171     void Utils::fillErrorMsg(ParserChar* dest, const ParserChar* src, size_t maxLen)
172     {
173         size_t bufferLength = 0;
174         while (src[bufferLength])
175             ++bufferLength;
176         size_t length = std::min(maxLen, bufferLength);
177         memcpy(dest, src, length);
178         dest[length] = '\0';
179     }
180 
181     //--------------------------------------------------------------------
182 	template<class FloatingPointType>
toFloatingPoint(const ParserChar ** buffer,const ParserChar * bufferEnd,bool & failed)183 	FloatingPointType Utils::toFloatingPoint(const ParserChar** buffer, const ParserChar* bufferEnd, bool& failed)
184 	{
185 		const ParserChar* s = *buffer;
186 		if ( !s )
187 		{
188 			failed = true;
189 			return 0.0f;
190 		}
191 
192 		if ( s == bufferEnd )
193 		{
194 			failed = true;
195 			*buffer = bufferEnd;
196 			return 0.0f;
197 		}
198 
199 		// Skip leading white spaces
200 		while ( isWhiteSpace(*s) )
201 		{
202 			++s;
203 			if ( s == bufferEnd )
204 			{
205 				failed = true;
206 				*buffer = bufferEnd;
207 				return 0.0f;
208 			}
209 		}
210 
211         // check for 'NaN'
212         if ( s[0] == 'N' && s[1] == 'a' && s[2] == 'N' )
213         {
214             if ( &s[3] == bufferEnd || isWhiteSpace(s[3]) )
215             {
216                 *buffer = s + 3;
217                 failed = false;
218                 return std::numeric_limits<FloatingPointType>::quiet_NaN();
219             }
220             else
221             {
222                 *buffer = s;
223                 failed = true;
224                 return 0;
225             }
226         }
227 
228         double value = 0.0;
229 		FloatingPointType sign = 1.0;
230 		if (*s == '-')
231 		{
232 			++s;
233 			sign = -1.0;
234 		}
235 		else if (*s == '+')
236 		{
237 			++s;
238 		}
239 
240         // check for 'INF', '+INF', '-INF'
241         if ( s[0] == 'I' && s[1] == 'N' && s[2] == 'F' )
242         {
243             if ( &s[3] == bufferEnd || isWhiteSpace(s[3]) )
244             {
245                 *buffer = s + 3;
246                 failed = false;
247                 return sign * std::numeric_limits<FloatingPointType>::infinity();
248             }
249             else
250             {
251                 *buffer = s;
252                 failed = true;
253                 return 0;
254             }
255         }
256 
257 		bool charBeforeDecimalPoint = false;
258 		while ( true )
259 		{
260 			if ( s == bufferEnd )
261 			{
262 				if (charBeforeDecimalPoint)
263 				{
264 					failed = false;
265 					*buffer = s;
266 					return sign * (FloatingPointType)value;
267 				}
268 				else
269 				{
270 					failed = true;
271 					*buffer = s;
272 					return 0.0f;
273 				}
274 			}
275 
276 			if ( isdigit(*s) )
277 			{
278 				value = value * 10 + (*s - '0');
279 				charBeforeDecimalPoint = true;
280 			}
281 			else
282 				break;
283 			++s;
284 		}
285 
286 		if ( (*s=='.') )
287 			++s;
288 
289 		int power = 0;
290 		bool charAfterDecimalPoint = false;
291 		while ( true )
292 		{
293 			if ( s == bufferEnd )
294 			{
295 				if ( charBeforeDecimalPoint || charAfterDecimalPoint )
296 				{
297 					failed = false;
298 					*buffer = s;
299 					return (FloatingPointType)value * pow((FloatingPointType)10, (FloatingPointType)power) * sign;
300 				}
301 				else
302 				{
303 					failed = true;
304 					*buffer = s;
305 					return 0.0f;
306 				}
307 			}
308 
309 			if ( isdigit(*s) )
310 			{
311 				value = value * 10 + (*s - '0');
312 				--power;
313 				charAfterDecimalPoint = true;
314 			}
315 			else
316 				break;
317 			++s;
318 		}
319 
320 		if ( !charBeforeDecimalPoint && !charAfterDecimalPoint )
321 		{
322 			failed = true;
323 			*buffer = s;
324 			return 0.0f;
325 		}
326 
327 		if ( (*s == 'e') || (*s == 'E') )
328 		{
329 			++s;
330 			bool intFailed = false;
331 			sint32 exponent = toSint32(&s, bufferEnd, intFailed);
332 			if ( intFailed )
333 			{
334 				failed = true;
335 				*buffer = s;
336 				return 0.0f;
337 			}
338 			power += exponent;
339 		}
340 
341 		failed = false;
342 		*buffer = s;
343 		return (FloatingPointType)value * pow((FloatingPointType)10, (FloatingPointType)power) * sign;
344 	}
345 
346 
347 
348 	//--------------------------------------------------------------------
349 	template<class FloatingPointType>
toFloatingPoint(const ParserChar * buffer,bool & failed)350 	FloatingPointType Utils::toFloatingPoint(const ParserChar* buffer, bool& failed)
351 	{
352 		const ParserChar* s = buffer;
353 		if ( !s )
354 		{
355 			failed = true;
356 			return 0.0f;
357 		}
358 
359 		if ( *s == '\0' )
360 		{
361 			failed = true;
362 			return 0.0f;
363 		}
364 
365 		// Skip leading white spaces
366 		while ( isWhiteSpace(*s) )
367 		{
368 			++s;
369 			if ( *s == '\0' )
370 			{
371 				failed = true;
372 				return 0.0f;
373 			}
374 		}
375 
376         // check for 'NaN'
377         if ( s[0] == 'N' && s[1] == 'a' && s[2] == 'N' )
378         {
379             if ( s[3] == '\0' || isWhiteSpace(s[3]) )
380             {
381                 failed = false;
382                 return std::numeric_limits<FloatingPointType>::quiet_NaN();
383             }
384             else
385             {
386                 failed = true;
387                 return 0;
388             }
389         }
390 
391         double value = 0.0;
392 		FloatingPointType sign = 1.0;
393 		if (*s == '-')
394 		{
395 			++s;
396 			sign = -1.0;
397 		}
398 		else if (*s == '+')
399 		{
400 			++s;
401 		}
402 
403         // check for 'INF', '+INF', '-INF'
404         if ( s[0] == 'I' && s[1] == 'N' && s[2] == 'F' )
405         {
406             if ( s[3] == '\0' || isWhiteSpace(s[3]) )
407             {
408                 failed = false;
409                 return sign * std::numeric_limits<FloatingPointType>::infinity();
410             }
411             else
412             {
413                 failed = true;
414                 return 0;
415             }
416         }
417 
418 		bool charBeforeDecimalPoint = false;
419 		while ( true )
420 		{
421 			if ( *s == '\0' )
422 			{
423 				failed = false;
424 				return (FloatingPointType)value * sign;
425 			}
426 
427 			if ( isdigit(*s) )
428 			{
429 				value = value * 10 + (*s - '0');
430 				charBeforeDecimalPoint = true;
431 			}
432 			else
433 				break;
434 			++s;
435 		}
436 
437 		if ( (*s=='.') )
438 			++s;
439 
440 		int power = 0;
441 		bool charAfterDecimalPoint = false;
442 		while ( true )
443 		{
444 			if ( *s == '\0' )
445 			{
446 				if ( !charBeforeDecimalPoint && !charAfterDecimalPoint )
447 				{
448 					failed = true;
449 					return 0.0f;
450 				}
451 				else
452 				{
453 					failed = false;
454 					return (FloatingPointType)value * pow((FloatingPointType)10, (FloatingPointType)power) * sign;
455 				}
456 			}
457 
458 			if ( isdigit(*s) )
459 			{
460 				value = value * 10 + (*s - '0');
461 				--power;
462 				charAfterDecimalPoint = true;
463 			}
464 			else
465 				break;
466 			++s;
467 		}
468 
469 		if ( !charBeforeDecimalPoint && !charAfterDecimalPoint )
470 		{
471 			failed = true;
472 			return 0.0f;
473 		}
474 
475 		if ( (*s == 'e') || (*s == 'E') )
476 		{
477 			++s;
478 			bool intFailed = false;
479 			sint32 exponent = toSint32(s, intFailed);
480 			if ( intFailed )
481 			{
482 				failed = true;
483 				return 0.0f;
484 			}
485 			power += exponent;
486 		}
487 
488 		failed = false;
489 		return (FloatingPointType)value * pow((FloatingPointType)10, (FloatingPointType)power) * sign;
490 	}
491 
492 
493     //--------------------------------------------------------------------
494     template<class FloatingPointType>
toFloatingPoint(const ParserChar ** buffer,bool & failed)495     FloatingPointType Utils::toFloatingPoint(const ParserChar** buffer, bool& failed)
496     {
497         const ParserChar* s = *buffer;
498         if ( !s )
499         {
500             failed = true;
501             return 0.0f;
502         }
503 
504         if ( *s == '\0' )
505         {
506             failed = true;
507             *buffer = s;
508             return 0.0f;
509         }
510 
511         // Skip leading white spaces
512         while ( isWhiteSpace(*s) )
513         {
514             ++s;
515             if ( *s == '\0' )
516             {
517                 failed = true;
518                 *buffer = s;
519                 return 0.0f;
520             }
521         }
522 
523         // check for 'NaN'
524         if ( s[0] == 'N' && s[1] == 'a' && s[2] == 'N' )
525         {
526             if ( s[3] == '\0' || isWhiteSpace(s[3]) )
527             {
528                 *buffer = s + 3;
529                 failed = false;
530                 return std::numeric_limits<FloatingPointType>::quiet_NaN();
531             }
532             else
533             {
534                 *buffer = s;
535                 failed = true;
536                 return 0;
537             }
538         }
539 
540         double value = 0.0;
541         FloatingPointType sign = 1.0;
542         if (*s == '-')
543         {
544             ++s;
545             sign = -1.0;
546         }
547         else if (*s == '+')
548         {
549             ++s;
550         }
551 
552         // check for 'INF', '+INF', '-INF'
553         if ( s[0] == 'I' && s[1] == 'N' && s[2] == 'F' )
554         {
555             if ( s[3] == '\0' || isWhiteSpace(s[3]) )
556             {
557                 *buffer = s + 3;
558                 failed = false;
559                 return sign * std::numeric_limits<FloatingPointType>::infinity();
560             }
561             else
562             {
563                 *buffer = s;
564                 failed = true;
565                 return 0;
566             }
567         }
568 
569         bool charBeforeDecimalPoint = false;
570         while ( true )
571         {
572             if ( *s == '\0' )
573             {
574                 if (charBeforeDecimalPoint)
575                 {
576                     failed = false;
577                     *buffer = s;
578                     return sign * (FloatingPointType)value;
579                 }
580                 else
581                 {
582                     failed = true;
583                     *buffer = s;
584                     return 0.0f;
585                 }
586             }
587 
588             if ( isdigit(*s) )
589             {
590                 value = value * 10 + (*s - '0');
591                 charBeforeDecimalPoint = true;
592             }
593             else
594                 break;
595             ++s;
596         }
597 
598         if ( (*s=='.') )
599             ++s;
600 
601         int power = 0;
602         bool charAfterDecimalPoint = false;
603         while ( true )
604         {
605             if ( *s == '\0' )
606             {
607                 if ( charBeforeDecimalPoint || charAfterDecimalPoint )
608                 {
609                     failed = false;
610                     *buffer = s;
611                     return (FloatingPointType)value * pow((FloatingPointType)10, (FloatingPointType)power) * sign;
612                 }
613                 else
614                 {
615                     failed = true;
616                     *buffer = s;
617                     return 0.0f;
618                 }
619             }
620 
621             if ( isdigit(*s) )
622             {
623                 value = value * 10 + (*s - '0');
624                 --power;
625                 charAfterDecimalPoint = true;
626             }
627             else
628                 break;
629             ++s;
630         }
631 
632         if ( !charBeforeDecimalPoint && !charAfterDecimalPoint )
633         {
634             failed = true;
635             *buffer = s;
636             return 0.0f;
637         }
638 
639         if ( (*s == 'e') || (*s == 'E') )
640         {
641             ++s;
642             bool intFailed = false;
643             sint32 exponent = toSint32(&s, intFailed);
644             if ( intFailed )
645             {
646                 failed = true;
647                 *buffer = s;
648                 return 0.0f;
649             }
650             power += exponent;
651         }
652 
653         failed = false;
654         *buffer = s;
655         return (FloatingPointType)value * pow((FloatingPointType)10, (FloatingPointType)power) * sign;
656     }
657 
658 
659 	//--------------------------------------------------------------------
toFloat(const ParserChar ** buffer,const ParserChar * bufferEnd,bool & failed)660 	float Utils::toFloat( const ParserChar** buffer, const ParserChar* bufferEnd, bool& failed )
661 	{
662 		return toFloatingPoint<float>(buffer, bufferEnd, failed);
663 	}
664 
665 
666 	//--------------------------------------------------------------------
toFloat(const ParserChar * buffer,bool & failed)667 	float Utils::toFloat( const ParserChar* buffer, bool& failed )
668 	{
669 		return toFloatingPoint<float>(buffer, failed);
670 	}
671 
672 
673     //--------------------------------------------------------------------
toFloat(const ParserChar ** buffer,bool & failed)674     float Utils::toFloat( const ParserChar** buffer, bool& failed )
675     {
676         return toFloatingPoint<float>(buffer, failed);
677     }
678 
679 
680 	//--------------------------------------------------------------------
toDouble(const ParserChar ** buffer,const ParserChar * bufferEnd,bool & failed)681 	double Utils::toDouble( const ParserChar** buffer, const ParserChar* bufferEnd, bool& failed )
682 	{
683 		return toFloatingPoint<double>(buffer, bufferEnd, failed);
684 	}
685 
686 
687 	//--------------------------------------------------------------------
toDouble(const ParserChar * buffer,bool & failed)688 	double Utils::toDouble( const ParserChar* buffer, bool& failed )
689 	{
690 		return toFloatingPoint<double>(buffer, failed);
691 	}
692 
693 
694     //--------------------------------------------------------------------
toDouble(const ParserChar ** buffer,bool & failed)695     double Utils::toDouble( const ParserChar** buffer, bool& failed )
696     {
697         return toFloatingPoint<double>(buffer, failed);
698     }
699 
700     //--------------------------------------------------------------------
toStringListItem(const ParserChar ** buffer,const ParserChar * bufferEnd,bool & failed)701     ParserString Utils::toStringListItem(const ParserChar** buffer, const ParserChar* bufferEnd, bool& failed)
702     {
703         ParserString value;
704 
705         const ParserChar* s = *buffer;
706         if ( !s )
707         {
708             failed = true;
709             return value;
710         }
711 
712         if ( s == bufferEnd )
713         {
714             failed = true;
715             *buffer = bufferEnd;
716             return value;
717         }
718 
719         // Skip leading white spaces
720         while ( isWhiteSpace(*s) )
721         {
722             ++s;
723             if ( s == bufferEnd )
724             {
725                 failed = true;
726                 *buffer = bufferEnd;
727                 return value;
728             }
729         }
730 
731         bool characterFound = false;
732         while (true)
733         {
734             if ( s == bufferEnd )
735             {
736                 if (characterFound)
737                 {
738                     failed = false;
739                     *buffer = s;
740                     return value;
741                 }
742                 else
743                 {
744                     failed = true;
745                     *buffer = s;
746                     value.str = 0;
747                     value.length = 0;
748                     return value;
749                 }
750             }
751 
752             if ( !isWhiteSpace(*s) )
753             {
754                 if (!characterFound)
755                 {
756                     value.str = s;
757                     characterFound = true;
758                 }
759                 value.length++;
760             }
761             else
762                 break;
763             ++s;
764         }
765         if ( characterFound )
766         {
767             *buffer = s;
768             failed = false;
769             return value;
770         }
771         else
772         {
773             failed = true;
774             *buffer = s;
775             value.str = 0;
776             value.length = 0;
777             return value;
778         }
779     }
780 
781     //--------------------------------------------------------------------
toStringListItem(const ParserChar ** buffer,bool & failed)782     ParserString Utils::toStringListItem(const ParserChar** buffer, bool& failed)
783     {
784         ParserString value;
785 
786         const ParserChar* s = *buffer;
787         if ( !s )
788         {
789             failed = true;
790             return value;
791         }
792 
793         if ( *s == '\0' )
794         {
795             failed = true;
796             *buffer = s;
797             return value;
798         }
799 
800         // Skip leading white spaces
801         while ( isWhiteSpace(*s) )
802         {
803             ++s;
804             if ( *s == '\0' )
805             {
806                 failed = true;
807                 *buffer = s;
808                 return value;
809             }
810         }
811 
812         bool characterFound = false;
813         while (true)
814         {
815             if ( *s == '\0' )
816             {
817                 if (characterFound)
818                 {
819                     failed = false;
820                     *buffer = s;
821                     return value;
822                 }
823                 else
824                 {
825                     failed = true;
826                     *buffer = s;
827                     value.str = 0;
828                     value.length = 0;
829                     return value;
830                 }
831             }
832 
833             if ( !isWhiteSpace(*s) )
834             {
835                 if (!characterFound)
836                 {
837                     value.str = s;
838                     characterFound = true;
839                 }
840                 value.length++;
841             }
842             else
843                 break;
844             ++s;
845         }
846         if ( characterFound )
847         {
848             *buffer = s;
849             failed = false;
850             return value;
851         }
852         else
853         {
854             failed = true;
855             *buffer = s;
856             value.str = 0;
857             value.length = 0;
858             return value;
859         }
860     }
861 
862 
863     //--------------------------------------------------------------------
toURI(const ParserChar ** buffer,const ParserChar * bufferEnd,bool & failed)864     COLLADABU::URI Utils::toURI(const ParserChar** buffer, const ParserChar* bufferEnd, bool& failed)
865     {
866         if ( *buffer == bufferEnd )
867         {
868             failed = false;
869             return COLLADABU::URI(0);
870         }
871         const ParserString& string = toStringListItem(buffer, bufferEnd, failed);
872         return COLLADABU::URI(string.str, string.length);
873 
874         //FIXME: Testing fails on windows but pass on OSX with this fix.
875         //Just get the string as it is for ids, so that we are able to read FBX-COLLADA
876         //Otherwise, calling toStringItem would result in a truncated string when an id contains spaces
877         //return COLLADABU::URI((const char*)*buffer, bufferEnd - *buffer);
878     }
879 
880     //--------------------------------------------------------------------
toURI(const ParserChar ** buffer,bool & failed)881     COLLADABU::URI Utils::toURI(const ParserChar** buffer, bool& failed)
882     {
883         if ( **buffer == '\0' )
884         {
885             failed = false;
886             return COLLADABU::URI(0);
887         }
888 
889         const ParserString& string = toStringListItem(buffer, failed);
890         return COLLADABU::URI(string.str, string.length);
891 
892         //FIXME: Testing fails on windows but pass on OSX with this fix.
893         //Just get the string as it is for ids, so that we are able to read FBX-COLLADA
894         //Otherwise, calling toStringItem would result in a truncated string when an id contains spaces
895         //return COLLADABU::URI((const char*)*buffer);
896     }
897 
898 
899     //--------------------------------------------------------------------
900 	template<class IntegerType, bool signedInteger>
901 	IntegerType Utils::toInteger(const ParserChar** buffer, const ParserChar* bufferEnd, bool& failed)
902 	{
903 		const ParserChar* s = *buffer;
904 		if ( !s )
905 		{
906 			failed = true;
907 			return 0;
908 		}
909 
910 		if ( s == bufferEnd )
911 		{
912 			failed = true;
913 			*buffer = bufferEnd;
914 			return 0;
915 		}
916 
917 		// Skip leading white spaces
918 		while ( isWhiteSpace(*s) )
919 		{
920 			++s;
921 			if ( s == bufferEnd )
922 			{
923 				failed = true;
924 				*buffer = bufferEnd;
925 				return 0;
926 			}
927 		}
928 
929 		IntegerType value = 0;
930 		IntegerType sign = 1;
931 		if ( signedInteger )
932 		{
933 			if (*s == '-')
934 			{
935 				++s;
936 				sign = -1;
937 			}
938 			else if (*s == '+')
939 			{
940 				++s;
941 			}
942 		}
943 
944 		bool digitFound = false;
945 		while (true)
946 		{
947 			if ( s == bufferEnd )
948 			{
949 				if (digitFound)
950 				{
951 					failed = false;
952 					*buffer = s;
953 					if ( signedInteger )
954 						return value * sign;
955 					else
956 						return value;
957 				}
958 				else
959 				{
960 					failed = true;
961 					*buffer = s;
962 					return 0;
963 				}
964 			}
965 
966 			if ( isdigit(*s) )
967 			{
968 				value = value * 10 + (*s - '0');
969 				digitFound = true;
970 			}
971 			else
972 				break;
973 			++s;
974 		}
975 		if ( digitFound )
976 		{
977 			*buffer = s;
978 			failed = false;
979 			if ( signedInteger )
980 				return value * sign;
981 			else
982 				return value;
983 		}
984 		else
985 		{
986 			failed = true;
987 			*buffer = s;
988 			return 0;
989 		}
990 	}
991 
992 
993 	//--------------------------------------------------------------------
994 	template<class IntegerType, bool signedInteger>
995 	IntegerType Utils::toInteger(const ParserChar* buffer, bool& failed)
996 	{
997 		const ParserChar* s = buffer;
998 		if ( !s )
999 		{
1000 			failed = true;
1001 			return 0;
1002 		}
1003 
1004 		if ( *s == '\0' )
1005 		{
1006 			failed = true;
1007 			return 0;
1008 		}
1009 
1010 		// Skip leading white spaces
1011 		while ( isWhiteSpace(*s) )
1012 		{
1013 			++s;
1014 			if ( *s == '\0' )
1015 			{
1016 				failed = true;
1017 				return 0;
1018 			}
1019 		}
1020 
1021 		IntegerType value = 0;
1022 		IntegerType sign = 1;
1023 		if ( signedInteger )
1024 		{
1025 			if (*s == '-')
1026 			{
1027 				++s;
1028 				sign = -1;
1029 			}
1030 			else if (*s == '+')
1031 			{
1032 				++s;
1033 			}
1034 		}
1035 
1036 		bool digitFound = false;
1037 		while (true)
1038 		{
1039 			if ( *s == '\0' )
1040 			{
1041 				failed = false;
1042 				return value * sign;
1043 			}
1044 
1045 			if ( isdigit(*s) )
1046 			{
1047 				value = value * 10 + (*s - '0');
1048 				digitFound = true;
1049 			}
1050 			else
1051 			{
1052 				break;
1053 			}
1054 			++s;
1055 		}
1056 		if ( digitFound )
1057 		{
1058 			failed = false;
1059 			if ( signedInteger )
1060 				return value * sign;
1061 			else
1062 				return value;
1063 		}
1064 		else
1065 		{
1066 			failed = true;
1067 			return 0;
1068 		}
1069 	}
1070 
1071     //--------------------------------------------------------------------
1072     template<class IntegerType, bool signedInteger>
1073     IntegerType Utils::toInteger(const ParserChar** buffer, bool& failed)
1074     {
1075         const ParserChar* s = *buffer;
1076         if ( !s )
1077         {
1078             failed = true;
1079             return 0;
1080         }
1081 
1082         if ( *s == '\0' )
1083         {
1084             failed = true;
1085             *buffer = s;
1086             return 0;
1087         }
1088 
1089         // Skip leading white spaces
1090         while ( isWhiteSpace(*s) )
1091         {
1092             ++s;
1093             if ( *s == '\0' )
1094             {
1095                 failed = true;
1096                 *buffer = s;
1097                 return 0;
1098             }
1099         }
1100 
1101         IntegerType value = 0;
1102         IntegerType sign = 1;
1103         if ( signedInteger )
1104         {
1105             if (*s == '-')
1106             {
1107                 ++s;
1108                 sign = -1;
1109             }
1110             else if (*s == '+')
1111             {
1112                 ++s;
1113             }
1114         }
1115 
1116         bool digitFound = false;
1117         while (true)
1118         {
1119             if ( *s == '\0' )
1120             {
1121                 if (digitFound)
1122                 {
1123                     failed = false;
1124                     *buffer = s;
1125                     if ( signedInteger )
1126                         return value * sign;
1127                     else
1128                         return value;
1129                 }
1130                 else
1131                 {
1132                     failed = true;
1133                     *buffer = s;
1134                     return 0;
1135                 }
1136             }
1137 
1138             if ( isdigit(*s) )
1139             {
1140                 value = value * 10 + (*s - '0');
1141                 digitFound = true;
1142             }
1143             else
1144                 break;
1145             ++s;
1146         }
1147         if ( digitFound )
1148         {
1149             *buffer = s;
1150             failed = false;
1151             if ( signedInteger )
1152                 return value * sign;
1153             else
1154                 return value;
1155         }
1156         else
1157         {
1158             failed = true;
1159             *buffer = s;
1160             return 0;
1161         }
1162     }
1163 
1164 	//--------------------------------------------------------------------
toSint8(const ParserChar ** buffer,const ParserChar * bufferEnd,bool & failed)1165 	sint8 Utils::toSint8( const ParserChar** buffer, const ParserChar* bufferEnd, bool& failed )
1166 	{
1167 		return toInteger<sint8, true>(buffer, bufferEnd, failed);
1168 	}
1169 
1170 	//--------------------------------------------------------------------
toSint8(const ParserChar * buffer,bool & failed)1171 	sint8 Utils::toSint8( const ParserChar* buffer, bool& failed )
1172 	{
1173 		return toInteger<sint8, true>(buffer, failed);
1174 	}
1175 
1176     //--------------------------------------------------------------------
toSint8(const ParserChar ** buffer,bool & failed)1177     sint8 Utils::toSint8( const ParserChar** buffer, bool& failed )
1178     {
1179         return toInteger<sint8, true>(buffer, failed);
1180     }
1181 
1182 	//--------------------------------------------------------------------
toUint8(const ParserChar ** buffer,const ParserChar * bufferEnd,bool & failed)1183 	uint8 Utils::toUint8( const ParserChar** buffer, const ParserChar* bufferEnd, bool& failed )
1184 	{
1185 		return toInteger<uint8, false>(buffer, bufferEnd, failed);
1186 	}
1187 
1188 	//--------------------------------------------------------------------
toUint8(const ParserChar * buffer,bool & failed)1189 	uint8 Utils::toUint8( const ParserChar* buffer, bool& failed )
1190 	{
1191 		return toInteger<uint8, false>(buffer, failed);
1192 	}
1193 
1194     //--------------------------------------------------------------------
toUint8(const ParserChar ** buffer,bool & failed)1195     uint8 Utils::toUint8( const ParserChar** buffer, bool& failed )
1196     {
1197         return toInteger<uint8, false>(buffer, failed);
1198     }
1199 
1200 	//--------------------------------------------------------------------
toSint16(const ParserChar ** buffer,const ParserChar * bufferEnd,bool & failed)1201 	sint16 Utils::toSint16( const ParserChar** buffer, const ParserChar* bufferEnd, bool& failed )
1202 	{
1203 		return toInteger<sint16, true>(buffer, bufferEnd, failed);
1204 	}
1205 
1206 	//--------------------------------------------------------------------
toSint16(const ParserChar * buffer,bool & failed)1207 	sint16 Utils::toSint16( const ParserChar* buffer, bool& failed )
1208 	{
1209 		return toInteger<sint16, true>(buffer, failed);
1210 	}
1211 
1212     //--------------------------------------------------------------------
toSint16(const ParserChar ** buffer,bool & failed)1213     sint16 Utils::toSint16( const ParserChar** buffer, bool& failed )
1214     {
1215         return toInteger<sint16, true>(buffer, failed);
1216     }
1217 
1218 	//--------------------------------------------------------------------
toUint16(const ParserChar ** buffer,const ParserChar * bufferEnd,bool & failed)1219 	uint16 Utils::toUint16( const ParserChar** buffer, const ParserChar* bufferEnd, bool& failed )
1220 	{
1221 		return toInteger<uint16, false>(buffer, bufferEnd, failed);
1222 	}
1223 
1224 	//--------------------------------------------------------------------
toUint16(const ParserChar * buffer,bool & failed)1225 	uint16 Utils::toUint16( const ParserChar* buffer, bool& failed )
1226 	{
1227 		return toInteger<uint16, false>(buffer, failed);
1228 	}
1229 
1230     //--------------------------------------------------------------------
toUint16(const ParserChar ** buffer,bool & failed)1231     uint16 Utils::toUint16( const ParserChar** buffer, bool& failed )
1232     {
1233         return toInteger<uint16, false>(buffer, failed);
1234     }
1235 
1236 	//--------------------------------------------------------------------
toSint32(const ParserChar ** buffer,const ParserChar * bufferEnd,bool & failed)1237 	sint32 Utils::toSint32( const ParserChar** buffer, const ParserChar* bufferEnd, bool& failed )
1238 	{
1239 		return toInteger<sint32, true>(buffer, bufferEnd, failed);
1240 	}
1241 
1242 	//--------------------------------------------------------------------
toSint32(const ParserChar * buffer,bool & failed)1243 	sint32 Utils::toSint32( const ParserChar* buffer, bool& failed )
1244 	{
1245 		return toInteger<sint32, true>(buffer, failed);
1246 	}
1247 
1248     //--------------------------------------------------------------------
toSint32(const ParserChar ** buffer,bool & failed)1249     sint32 Utils::toSint32( const ParserChar** buffer, bool& failed )
1250     {
1251         return toInteger<sint32, true>(buffer, failed);
1252     }
1253 
1254     //--------------------------------------------------------------------
toUint32(const ParserChar ** buffer,const ParserChar * bufferEnd,bool & failed)1255     uint32 Utils::toUint32( const ParserChar** buffer, const ParserChar* bufferEnd, bool& failed )
1256     {
1257         return toInteger<uint32, false>(buffer, bufferEnd, failed);
1258     }
1259 
1260     //--------------------------------------------------------------------
toUint32(const ParserChar * buffer,bool & failed)1261     uint32 Utils::toUint32( const ParserChar* buffer, bool& failed )
1262     {
1263         return toInteger<uint32, false>(buffer, failed);
1264     }
1265 
1266     //--------------------------------------------------------------------
toUint32(const ParserChar ** buffer,bool & failed)1267     uint32 Utils::toUint32( const ParserChar** buffer, bool& failed )
1268     {
1269         return toInteger<uint32, false>(buffer, failed);
1270     }
1271 
1272     //--------------------------------------------------------------------
toSint64(const ParserChar ** buffer,const ParserChar * bufferEnd,bool & failed)1273     sint64 Utils::toSint64( const ParserChar** buffer, const ParserChar* bufferEnd, bool& failed )
1274     {
1275         return toInteger<sint64, true>(buffer, bufferEnd, failed);
1276     }
1277 
1278     //--------------------------------------------------------------------
toSint64(const ParserChar * buffer,bool & failed)1279     sint64 Utils::toSint64( const ParserChar* buffer, bool& failed )
1280     {
1281         return toInteger<sint64, true>(buffer, failed);
1282     }
1283 
1284     //--------------------------------------------------------------------
toSint64(const ParserChar ** buffer,bool & failed)1285     sint64 Utils::toSint64( const ParserChar** buffer, bool& failed )
1286     {
1287         return toInteger<sint64, true>(buffer, failed);
1288     }
1289 
1290     //--------------------------------------------------------------------
toUint64(const ParserChar ** buffer,const ParserChar * bufferEnd,bool & failed)1291     uint64 Utils::toUint64( const ParserChar** buffer, const ParserChar* bufferEnd, bool& failed )
1292     {
1293         return toInteger<uint64, false>(buffer, bufferEnd, failed);
1294     }
1295 
1296     //--------------------------------------------------------------------
toUint64(const ParserChar * buffer,bool & failed)1297     uint64 Utils::toUint64( const ParserChar* buffer, bool& failed )
1298     {
1299         return toInteger<uint64, false>(buffer, failed);
1300     }
1301 
1302     //--------------------------------------------------------------------
toUint64(const ParserChar ** buffer,bool & failed)1303     uint64 Utils::toUint64( const ParserChar** buffer, bool& failed )
1304     {
1305         return toInteger<uint64, false>(buffer, failed);
1306     }
1307 
1308 	//--------------------------------------------------------------------
toBool(const ParserChar * buffer,bool & failed)1309 	bool Utils::toBool( const ParserChar* buffer, bool& failed  )
1310 	{
1311 		if ( (strcmp((char*)buffer, "1") == 0) || (strcmp((char*)buffer, "true") == 0) )
1312 		{
1313 			failed = false;
1314 			return true;
1315 		}
1316 
1317 		if ( (strcmp((char*)buffer, "0") == 0) || (strcmp((char*)buffer, "false") == 0) )
1318 		{
1319 			failed = false;
1320 			return false;
1321 		}
1322 
1323 		failed = true;
1324 		return false;
1325 	}
1326 
1327 	//--------------------------------------------------------------------
toBool(const ParserChar ** buffer,const ParserChar * bufferEnd,bool & failed)1328 	bool Utils::toBool( const ParserChar** buffer, const ParserChar* bufferEnd, bool& failed  )
1329 	{
1330 		const ParserChar* s = *buffer;
1331 		if ( s == bufferEnd )
1332 		{
1333 			failed = true;
1334 			return true;
1335 		}
1336 
1337 		// Skip leading white spaces
1338 		while ( isWhiteSpace(*s) )
1339 		{
1340 			++s;
1341 			if ( s == bufferEnd )
1342 			{
1343 				failed = true;
1344 				*buffer = bufferEnd;
1345 				return true;
1346 			}
1347 		}
1348 
1349 
1350 		if ( *s == '1' )
1351 		{
1352 			failed = false;
1353 			*buffer = s + 1;
1354 			return true;
1355 		}
1356 		else if ( *s == '0' )
1357 		{
1358 			failed = false;
1359 			*buffer = s + 1;
1360 			return false;
1361 		}
1362 		else if ( *s == 't' )
1363 		{
1364 			s++;
1365 			static const char* trueString = "rue";
1366 			const ParserChar* c = (const ParserChar* )trueString;
1367 			while (true)
1368 			{
1369 				if ( *c == '\0' )
1370 				{
1371 					failed = false;
1372 					*buffer = s;
1373 					return true;
1374 				}
1375 				if ( s == bufferEnd )
1376 				{
1377 					failed = true;
1378 					*buffer = bufferEnd;
1379 					return true;
1380 				}
1381 				if ( *s == *c)
1382 				{
1383 					s++;
1384 					c++;
1385 				}
1386 				else
1387 				{
1388 					failed = true;
1389 					*buffer = s;
1390 					return true;
1391 				}
1392 			}
1393 		}
1394 		else if ( *s == 'f' )
1395 		{
1396 			s++;
1397 			static const char* trueString = "alse";
1398 			const ParserChar* c = (const ParserChar* )trueString;
1399 			while (true)
1400 			{
1401 				if ( *c == '\0' )
1402 				{
1403 					failed = false;
1404 					*buffer = s;
1405 					return false;
1406 				}
1407 				if ( s == bufferEnd )
1408 				{
1409 					failed = true;
1410 					*buffer = bufferEnd;
1411 					return true;
1412 				}
1413 				if ( *s == *c)
1414 				{
1415 					s++;
1416 					c++;
1417 				}
1418 				else
1419 				{
1420 					failed = true;
1421 					*buffer = s;
1422 					return true;
1423 				}
1424 			}
1425 		}
1426 
1427 		failed = true;
1428 		return false;
1429 	}
1430 
1431     //--------------------------------------------------------------------
toBool(const ParserChar ** buffer,bool & failed)1432     bool Utils::toBool( const ParserChar** buffer, bool& failed  )
1433     {
1434         const ParserChar* s = *buffer;
1435         if ( *s == '\0' )
1436         {
1437             failed = true;
1438             return true;
1439         }
1440 
1441         // Skip leading white spaces
1442         while ( isWhiteSpace(*s) )
1443         {
1444             ++s;
1445             if ( *s == '\0' )
1446             {
1447                 failed = true;
1448                 *buffer = s;
1449                 return true;
1450             }
1451         }
1452 
1453 
1454         if ( *s == '1' )
1455         {
1456             failed = false;
1457             *buffer = s + 1;
1458             return true;
1459         }
1460         else if ( *s == '0' )
1461         {
1462             failed = false;
1463             *buffer = s + 1;
1464             return false;
1465         }
1466         else if ( *s == 't' )
1467         {
1468             s++;
1469             static const char* trueString = "rue";
1470             const ParserChar* c = (const ParserChar* )trueString;
1471             while (true)
1472             {
1473                 if ( *c == '\0' )
1474                 {
1475                     failed = false;
1476                     *buffer = s;
1477                     return true;
1478                 }
1479                 if ( *s == '\0' )
1480                 {
1481                     failed = true;
1482                     *buffer = s;
1483                     return true;
1484                 }
1485                 if ( *s == *c)
1486                 {
1487                     s++;
1488                     c++;
1489                 }
1490                 else
1491                 {
1492                     failed = true;
1493                     *buffer = s;
1494                     return true;
1495                 }
1496             }
1497         }
1498         else if ( *s == 'f' )
1499         {
1500             s++;
1501             static const char* trueString = "alse";
1502             const ParserChar* c = (const ParserChar* )trueString;
1503             while (true)
1504             {
1505                 if ( *c == '\0' )
1506                 {
1507                     failed = false;
1508                     *buffer = s;
1509                     return false;
1510                 }
1511                 if ( *s == '\0' )
1512                 {
1513                     failed = true;
1514                     *buffer = s;
1515                     return true;
1516                 }
1517                 if ( *s == *c)
1518                 {
1519                     s++;
1520                     c++;
1521                 }
1522                 else
1523                 {
1524                     failed = true;
1525                     *buffer = s;
1526                     return true;
1527                 }
1528             }
1529         }
1530 
1531         failed = true;
1532         return false;
1533     }
1534 
1535     //--------------------------------------------------------------------
1536     template<typename T>
isInf(T value)1537     bool GeneratedSaxParser::Utils::isInf( T value )
1538     {
1539         return value == std::numeric_limits<T>::infinity();
1540     }
1541 
1542     //--------------------------------------------------------------------
1543     template<typename T>
isNegativeInf(T value)1544     bool GeneratedSaxParser::Utils::isNegativeInf( T value )
1545     {
1546         return value == -std::numeric_limits<T>::infinity();
1547     }
1548 
1549     //--------------------------------------------------------------------
1550     template<typename T>
isNaN(T value)1551     bool GeneratedSaxParser::Utils::isNaN( T value )
1552     {
1553 #if defined(COLLADABU_OS_WIN) && !defined(__MINGW32__)
1554         return _isnan( value ) ? true : false;
1555 #else
1556 #ifdef isnan
1557         return isnan( value );
1558 #else
1559         return std::isnan(value);
1560 #endif
1561 #endif
1562     }
1563 
1564     //--------------------------------------------------------------------
isInf(float value)1565     bool Utils::isInf( float value )
1566     {
1567         return isInf<float>( value );
1568     }
1569 
1570     //--------------------------------------------------------------------
isInf(double value)1571     bool Utils::isInf( double value )
1572     {
1573         return isInf<double>( value );
1574     }
1575 
1576     //--------------------------------------------------------------------
isNegativeInf(float value)1577     bool Utils::isNegativeInf( float value )
1578     {
1579         return isNegativeInf<float>( value );
1580     }
1581 
1582     //--------------------------------------------------------------------
isNegativeInf(double value)1583     bool Utils::isNegativeInf( double value )
1584     {
1585         return isNegativeInf<double>( value );
1586     }
1587 
1588     //--------------------------------------------------------------------
isNaN(float value)1589     bool Utils::isNaN( float value )
1590     {
1591         return isNaN<float>( value );
1592     }
1593 
1594     //--------------------------------------------------------------------
isNaN(double value)1595     bool Utils::isNaN( double value )
1596     {
1597         return isNaN<double>( value );
1598     }
1599 
1600 } // namespace GeneratedSaxParser
1601