diff options
author | Jacek Antonelli | 2009-04-30 13:04:20 -0500 |
---|---|---|
committer | Jacek Antonelli | 2009-04-30 13:07:16 -0500 |
commit | ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e (patch) | |
tree | 8348301d0ac44a524f1819b777686bf086907d76 /linden/indra/llcommon/llsdserialize_xml.cpp | |
parent | Second Life viewer sources 1.22.11 (diff) | |
download | meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.zip meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.gz meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.bz2 meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.xz |
Second Life viewer sources 1.23.0-RC
Diffstat (limited to 'linden/indra/llcommon/llsdserialize_xml.cpp')
-rw-r--r-- | linden/indra/llcommon/llsdserialize_xml.cpp | 179 |
1 files changed, 146 insertions, 33 deletions
diff --git a/linden/indra/llcommon/llsdserialize_xml.cpp b/linden/indra/llcommon/llsdserialize_xml.cpp index 6734ed4..c12ca35 100644 --- a/linden/indra/llcommon/llsdserialize_xml.cpp +++ b/linden/indra/llcommon/llsdserialize_xml.cpp | |||
@@ -17,7 +17,8 @@ | |||
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | 20 | * online at |
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | 22 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
@@ -318,8 +319,8 @@ private: | |||
318 | bool mSkipping; | 319 | bool mSkipping; |
319 | int mSkipThrough; | 320 | int mSkipThrough; |
320 | 321 | ||
321 | std::string mCurrentKey; | 322 | std::string mCurrentKey; // Current XML <tag> |
322 | std::ostringstream mCurrentContent; | 323 | std::string mCurrentContent; // String data between <tag> and </tag> |
323 | }; | 324 | }; |
324 | 325 | ||
325 | 326 | ||
@@ -556,16 +557,50 @@ void LLSDXMLParser::Impl::parsePart(const char* buf, int len) | |||
556 | } | 557 | } |
557 | } | 558 | } |
558 | 559 | ||
560 | // Performance testing code | ||
561 | //#define XML_PARSER_PERFORMANCE_TESTS | ||
562 | |||
563 | #ifdef XML_PARSER_PERFORMANCE_TESTS | ||
564 | |||
565 | extern U64 totalTime(); | ||
566 | U64 readElementTime = 0; | ||
567 | U64 startElementTime = 0; | ||
568 | U64 endElementTime = 0; | ||
569 | U64 charDataTime = 0; | ||
570 | U64 parseTime = 0; | ||
571 | |||
572 | class XML_Timer | ||
573 | { | ||
574 | public: | ||
575 | XML_Timer( U64 * sum ) : mSum( sum ) | ||
576 | { | ||
577 | mStart = totalTime(); | ||
578 | } | ||
579 | ~XML_Timer() | ||
580 | { | ||
581 | *mSum += (totalTime() - mStart); | ||
582 | } | ||
583 | |||
584 | U64 * mSum; | ||
585 | U64 mStart; | ||
586 | }; | ||
587 | #endif // XML_PARSER_PERFORMANCE_TESTS | ||
588 | |||
559 | void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Char** attributes) | 589 | void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Char** attributes) |
560 | { | 590 | { |
591 | #ifdef XML_PARSER_PERFORMANCE_TESTS | ||
592 | XML_Timer timer( &startElementTime ); | ||
593 | #endif // XML_PARSER_PERFORMANCE_TESTS | ||
594 | |||
561 | ++mDepth; | 595 | ++mDepth; |
562 | if (mSkipping) | 596 | if (mSkipping) |
563 | { | 597 | { |
564 | return; | 598 | return; |
565 | } | 599 | } |
566 | 600 | ||
567 | Element element = readElement(name); | 601 | Element element = readElement(name); |
568 | mCurrentContent.str(""); | 602 | |
603 | mCurrentContent.clear(); | ||
569 | 604 | ||
570 | switch (element) | 605 | switch (element) |
571 | { | 606 | { |
@@ -645,6 +680,10 @@ void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Ch | |||
645 | 680 | ||
646 | void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name) | 681 | void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name) |
647 | { | 682 | { |
683 | #ifdef XML_PARSER_PERFORMANCE_TESTS | ||
684 | XML_Timer timer( &endElementTime ); | ||
685 | #endif // XML_PARSER_PERFORMANCE_TESTS | ||
686 | |||
648 | --mDepth; | 687 | --mDepth; |
649 | if (mSkipping) | 688 | if (mSkipping) |
650 | { | 689 | { |
@@ -669,7 +708,7 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name) | |||
669 | return; | 708 | return; |
670 | 709 | ||
671 | case ELEMENT_KEY: | 710 | case ELEMENT_KEY: |
672 | mCurrentKey = mCurrentContent.str(); | 711 | mCurrentKey = mCurrentContent; |
673 | return; | 712 | return; |
674 | 713 | ||
675 | default: | 714 | default: |
@@ -682,9 +721,6 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name) | |||
682 | LLSD& value = *mStack.back(); | 721 | LLSD& value = *mStack.back(); |
683 | mStack.pop_back(); | 722 | mStack.pop_back(); |
684 | 723 | ||
685 | std::string content = mCurrentContent.str(); | ||
686 | mCurrentContent.str(""); | ||
687 | |||
688 | switch (element) | 724 | switch (element) |
689 | { | 725 | { |
690 | case ELEMENT_UNDEF: | 726 | case ELEMENT_UNDEF: |
@@ -692,39 +728,59 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name) | |||
692 | break; | 728 | break; |
693 | 729 | ||
694 | case ELEMENT_BOOL: | 730 | case ELEMENT_BOOL: |
695 | value = content == "true" || content == "1"; | 731 | value = (mCurrentContent == "true" || mCurrentContent == "1"); |
696 | break; | 732 | break; |
697 | 733 | ||
698 | case ELEMENT_INTEGER: | 734 | case ELEMENT_INTEGER: |
699 | value = LLSD(content).asInteger(); | 735 | { |
736 | S32 i; | ||
737 | if ( sscanf(mCurrentContent.c_str(), "%d", &i ) == 1 ) | ||
738 | { // See if sscanf works - it's faster | ||
739 | value = i; | ||
740 | } | ||
741 | else | ||
742 | { | ||
743 | value = LLSD(mCurrentContent).asInteger(); | ||
744 | } | ||
745 | } | ||
700 | break; | 746 | break; |
701 | 747 | ||
702 | case ELEMENT_REAL: | 748 | case ELEMENT_REAL: |
703 | value = LLSD(content).asReal(); | 749 | { |
750 | F64 r; | ||
751 | if ( sscanf(mCurrentContent.c_str(), "%lf", &r ) == 1 ) | ||
752 | { // See if sscanf works - it's faster | ||
753 | value = r; | ||
754 | } | ||
755 | else | ||
756 | { | ||
757 | value = LLSD(mCurrentContent).asReal(); | ||
758 | } | ||
759 | } | ||
704 | break; | 760 | break; |
705 | 761 | ||
706 | case ELEMENT_STRING: | 762 | case ELEMENT_STRING: |
707 | value = content; | 763 | value = mCurrentContent; |
708 | break; | 764 | break; |
709 | 765 | ||
710 | case ELEMENT_UUID: | 766 | case ELEMENT_UUID: |
711 | value = LLSD(content).asUUID(); | 767 | value = LLSD(mCurrentContent).asUUID(); |
712 | break; | 768 | break; |
713 | 769 | ||
714 | case ELEMENT_DATE: | 770 | case ELEMENT_DATE: |
715 | value = LLSD(content).asDate(); | 771 | value = LLSD(mCurrentContent).asDate(); |
716 | break; | 772 | break; |
717 | 773 | ||
718 | case ELEMENT_URI: | 774 | case ELEMENT_URI: |
719 | value = LLSD(content).asURI(); | 775 | value = LLSD(mCurrentContent).asURI(); |
720 | break; | 776 | break; |
721 | 777 | ||
722 | case ELEMENT_BINARY: | 778 | case ELEMENT_BINARY: |
723 | { | 779 | { |
724 | S32 len = apr_base64_decode_len(content.c_str()); | 780 | S32 len = apr_base64_decode_len(mCurrentContent.c_str()); |
725 | std::vector<U8> data; | 781 | std::vector<U8> data; |
726 | data.resize(len); | 782 | data.resize(len); |
727 | len = apr_base64_decode_binary(&data[0], content.c_str()); | 783 | len = apr_base64_decode_binary(&data[0], mCurrentContent.c_str()); |
728 | data.resize(len); | 784 | data.resize(len); |
729 | value = data; | 785 | value = data; |
730 | break; | 786 | break; |
@@ -738,11 +794,17 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name) | |||
738 | // other values, map and array, have already been set | 794 | // other values, map and array, have already been set |
739 | break; | 795 | break; |
740 | } | 796 | } |
797 | |||
798 | mCurrentContent.clear(); | ||
741 | } | 799 | } |
742 | 800 | ||
743 | void LLSDXMLParser::Impl::characterDataHandler(const XML_Char* data, int length) | 801 | void LLSDXMLParser::Impl::characterDataHandler(const XML_Char* data, int length) |
744 | { | 802 | { |
745 | mCurrentContent.write(data, length); | 803 | #ifdef XML_PARSER_PERFORMANCE_TESTS |
804 | XML_Timer timer( &charDataTime ); | ||
805 | #endif // XML_PARSER_PERFORMANCE_TESTS | ||
806 | |||
807 | mCurrentContent.append(data, length); | ||
746 | } | 808 | } |
747 | 809 | ||
748 | 810 | ||
@@ -765,22 +827,69 @@ void LLSDXMLParser::Impl::sCharacterDataHandler( | |||
765 | } | 827 | } |
766 | 828 | ||
767 | 829 | ||
830 | /* | ||
831 | This code is time critical | ||
832 | |||
833 | This is a sample of tag occurances of text in simstate file with ~8000 objects. | ||
834 | A tag pair (<key>something</key>) counts is counted as two: | ||
835 | |||
836 | key - 2680178 | ||
837 | real - 1818362 | ||
838 | integer - 906078 | ||
839 | array - 295682 | ||
840 | map - 191818 | ||
841 | uuid - 177903 | ||
842 | binary - 175748 | ||
843 | string - 53482 | ||
844 | undef - 40353 | ||
845 | boolean - 33874 | ||
846 | llsd - 16332 | ||
847 | uri - 38 | ||
848 | date - 1 | ||
849 | */ | ||
768 | LLSDXMLParser::Impl::Element LLSDXMLParser::Impl::readElement(const XML_Char* name) | 850 | LLSDXMLParser::Impl::Element LLSDXMLParser::Impl::readElement(const XML_Char* name) |
769 | { | 851 | { |
770 | if (strcmp(name, "llsd") == 0) { return ELEMENT_LLSD; } | 852 | #ifdef XML_PARSER_PERFORMANCE_TESTS |
771 | if (strcmp(name, "undef") == 0) { return ELEMENT_UNDEF; } | 853 | XML_Timer timer( &readElementTime ); |
772 | if (strcmp(name, "boolean") == 0) { return ELEMENT_BOOL; } | 854 | #endif // XML_PARSER_PERFORMANCE_TESTS |
773 | if (strcmp(name, "integer") == 0) { return ELEMENT_INTEGER; } | 855 | |
774 | if (strcmp(name, "real") == 0) { return ELEMENT_REAL; } | 856 | XML_Char c = *name; |
775 | if (strcmp(name, "string") == 0) { return ELEMENT_STRING; } | 857 | switch (c) |
776 | if (strcmp(name, "uuid") == 0) { return ELEMENT_UUID; } | 858 | { |
777 | if (strcmp(name, "date") == 0) { return ELEMENT_DATE; } | 859 | case 'k': |
778 | if (strcmp(name, "uri") == 0) { return ELEMENT_URI; } | 860 | if (strcmp(name, "key") == 0) { return ELEMENT_KEY; } |
779 | if (strcmp(name, "binary") == 0) { return ELEMENT_BINARY; } | 861 | break; |
780 | if (strcmp(name, "map") == 0) { return ELEMENT_MAP; } | 862 | case 'r': |
781 | if (strcmp(name, "array") == 0) { return ELEMENT_ARRAY; } | 863 | if (strcmp(name, "real") == 0) { return ELEMENT_REAL; } |
782 | if (strcmp(name, "key") == 0) { return ELEMENT_KEY; } | 864 | break; |
783 | 865 | case 'i': | |
866 | if (strcmp(name, "integer") == 0) { return ELEMENT_INTEGER; } | ||
867 | break; | ||
868 | case 'a': | ||
869 | if (strcmp(name, "array") == 0) { return ELEMENT_ARRAY; } | ||
870 | break; | ||
871 | case 'm': | ||
872 | if (strcmp(name, "map") == 0) { return ELEMENT_MAP; } | ||
873 | break; | ||
874 | case 'u': | ||
875 | if (strcmp(name, "uuid") == 0) { return ELEMENT_UUID; } | ||
876 | if (strcmp(name, "undef") == 0) { return ELEMENT_UNDEF; } | ||
877 | if (strcmp(name, "uri") == 0) { return ELEMENT_URI; } | ||
878 | break; | ||
879 | case 'b': | ||
880 | if (strcmp(name, "binary") == 0) { return ELEMENT_BINARY; } | ||
881 | if (strcmp(name, "boolean") == 0) { return ELEMENT_BOOL; } | ||
882 | break; | ||
883 | case 's': | ||
884 | if (strcmp(name, "string") == 0) { return ELEMENT_STRING; } | ||
885 | break; | ||
886 | case 'l': | ||
887 | if (strcmp(name, "llsd") == 0) { return ELEMENT_LLSD; } | ||
888 | break; | ||
889 | case 'd': | ||
890 | if (strcmp(name, "date") == 0) { return ELEMENT_DATE; } | ||
891 | break; | ||
892 | } | ||
784 | return ELEMENT_UNKNOWN; | 893 | return ELEMENT_UNKNOWN; |
785 | } | 894 | } |
786 | 895 | ||
@@ -808,6 +917,10 @@ void LLSDXMLParser::parsePart(const char *buf, int len) | |||
808 | // virtual | 917 | // virtual |
809 | S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data) const | 918 | S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data) const |
810 | { | 919 | { |
920 | #ifdef XML_PARSER_PERFORMANCE_TESTS | ||
921 | XML_Timer timer( &parseTime ); | ||
922 | #endif // XML_PARSER_PERFORMANCE_TESTS | ||
923 | |||
811 | if (mParseLines) | 924 | if (mParseLines) |
812 | { | 925 | { |
813 | // Use line-based reading (faster code) | 926 | // Use line-based reading (faster code) |