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