aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llsdserialize_xml.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2009-04-30 13:04:20 -0500
committerJacek Antonelli2009-04-30 13:07:16 -0500
commitca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e (patch)
tree8348301d0ac44a524f1819b777686bf086907d76 /linden/indra/llcommon/llsdserialize_xml.cpp
parentSecond Life viewer sources 1.22.11 (diff)
downloadmeta-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.cpp179
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
565extern U64 totalTime();
566U64 readElementTime = 0;
567U64 startElementTime = 0;
568U64 endElementTime = 0;
569U64 charDataTime = 0;
570U64 parseTime = 0;
571
572class XML_Timer
573{
574public:
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
559void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Char** attributes) 589void 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
646void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name) 681void 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
743void LLSDXMLParser::Impl::characterDataHandler(const XML_Char* data, int length) 801void 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*/
768LLSDXMLParser::Impl::Element LLSDXMLParser::Impl::readElement(const XML_Char* name) 850LLSDXMLParser::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
809S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data) const 918S32 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)