From 2008f87f10d51a2f9372aa4a4d72e86ac94e1e81 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 13 May 2024 18:26:53 +0300 Subject: Revert "viewer#819 Avoid reading the same XML file multiple times" This reverts commit a865d423974ea06dffa47798c81e98e7570b02ec. Reason for revert: viewer#1420, reverting to not hold maint-A (is deepCopy not full?) --- indra/llxml/llcontrol.cpp | 24 +++++----- indra/llxml/llcontrol.h | 2 +- indra/llxml/llxmlnode.cpp | 114 ++++++++++++++-------------------------------- indra/llxml/llxmlnode.h | 38 +++++++--------- indra/llxml/llxmltree.cpp | 45 ++---------------- indra/llxml/llxmltree.h | 4 +- 6 files changed, 69 insertions(+), 158 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index 952ad3e8cd..c0f27e2c22 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -753,13 +753,13 @@ void LLControlGroup::setUntypedValue(std::string_view name, const LLSD& val) //--------------------------------------------------------------- // Returns number of controls loaded, so 0 if failure -U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, const std::string& xml, bool require_declaration, eControlType declare_as) +U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, bool require_declaration, eControlType declare_as) { std::string name; LLXmlTree xml_controls; - if (!xml_controls.parseString(xml)) + if (!xml_controls.parseFile(filename)) { LL_WARNS("Settings") << "Unable to open control file " << filename << LL_ENDL; return 0; @@ -772,7 +772,7 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, const std::s return 0; } - U32 validitems = 0; + U32 validitems = 0; S32 version; rootp->getAttributeS32("version", version); @@ -990,24 +990,24 @@ U32 LLControlGroup::saveToFile(const std::string& filename, bool nondefault_only U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_values, bool save_values) { LLSD settings; - - std::string xml = gDirUtilp->getFileContents(filename); - if (xml.empty()) + llifstream infile; + infile.open(filename.c_str()); + if(!infile.is_open()) { LL_WARNS("Settings") << "Cannot find file " << filename << " to load." << LL_ENDL; return 0; } - std::stringstream stream(xml); - if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(settings, stream)) + if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(settings, infile)) { + infile.close(); LL_WARNS("Settings") << "Unable to parse LLSD control file " << filename << ". Trying Legacy Method." << LL_ENDL; - return loadFromFileLegacy(filename, xml, true, TYPE_STRING); + return loadFromFileLegacy(filename, true, TYPE_STRING); } U32 validitems = 0; bool hidefromsettingseditor = false; - + for(LLSD::map_const_iterator itr = settings.beginMap(); itr != settings.endMap(); ++itr) { LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT; @@ -1019,7 +1019,7 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v persist = control_map["Persist"].asInteger()? LLControlVariable::PERSIST_NONDFT : LLControlVariable::PERSIST_NO; } - + // Sometimes we want to use the settings system to provide cheap persistence, but we // don't want the settings themselves to be easily manipulated in the UI because // doing so can cause support problems. So we have this option: @@ -1031,7 +1031,7 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v { hidefromsettingseditor = false; } - + // If the control exists just set the value from the input file. LLControlVariable* existing_control = getControl(name); if(existing_control) diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index e148b74292..a8bc584c48 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -300,7 +300,7 @@ public: // Returns number of controls loaded, 0 if failed // If require_declaration is false, will auto-declare controls it finds // as the given type. - U32 loadFromFileLegacy(const std::string& filename, const std::string& xml, bool require_declaration = true, eControlType declare_as = TYPE_STRING); + U32 loadFromFileLegacy(const std::string& filename, bool require_declaration = true, eControlType declare_as = TYPE_STRING); U32 saveToFile(const std::string& filename, bool nondefault_only); U32 loadFromFile(const std::string& filename, bool default_values = false, bool save_values = true); void resetToDefaults(); diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index dc60b1aa66..9c7ac66f01 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -137,19 +137,19 @@ LLXMLNode::LLXMLNode(const LLXMLNode& rhs) : } // returns a new copy of this node and all its children -LLXMLNodePtr LLXMLNode::deepCopy() const +LLXMLNodePtr LLXMLNode::deepCopy() { LLXMLNodePtr newnode = LLXMLNodePtr(new LLXMLNode(*this)); if (mChildren.notNull()) { - for (LLXMLChildList::const_iterator iter = mChildren->map.begin(); + for (LLXMLChildList::iterator iter = mChildren->map.begin(); iter != mChildren->map.end(); ++iter) { LLXMLNodePtr temp_ptr_for_gcc(iter->second->deepCopy()); newnode->addChild(temp_ptr_for_gcc); } } - for (LLXMLAttribList::const_iterator iter = mAttributes.begin(); + for (LLXMLAttribList::iterator iter = mAttributes.begin(); iter != mAttributes.end(); ++iter) { LLXMLNodePtr temp_ptr_for_gcc(iter->second->deepCopy()); @@ -650,82 +650,37 @@ bool LLXMLNode::updateNode( return true; } -static std::map sXMLCache; -static LLSharedMutex sXMLCacheMutex; - -static void saveToCache(const std::string& filename, const LLXMLNodePtr& node) -{ - LLXMLNodePtr node_copy = node->deepCopy(); - - LLExclusiveMutexLock lock(&sXMLCacheMutex); - sXMLCache.emplace(filename, node_copy); -} - -static bool loadFromCache(const std::string& filename, LLXMLNodePtr& node) +// static +bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXMLNode* defaults_tree) { - LLSharedMutexLock lock(&sXMLCacheMutex); - auto it = sXMLCache.find(filename); - if (it == sXMLCache.end()) - return false; - node = it->second->deepCopy(); - return true; -} + // Read file + LL_DEBUGS("XMLNode") << "parsing XML file: " << filename << LL_ENDL; + LLFILE* fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */ + if (fp == NULL) + { + node = NULL ; + return false; + } + fseek(fp, 0, SEEK_END); + U32 length = ftell(fp); + fseek(fp, 0, SEEK_SET); -// static -bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXMLNode* defaults_tree, bool cacheable) -{ - // Try to read from cache - if (cacheable) - { - if (loadFromCache(filename, node)) - { - node->setDefault(defaults_tree); - node->updateDefault(); - return true; - } - } - - std::string xml = gDirUtilp->getFileContents(filename); - if (xml.empty()) - { - LL_WARNS("XMLNode") << "no XML file: " << filename << LL_ENDL; - } - else if (parseBuffer(xml.data(), xml.size(), node)) - { - if (cacheable) - { - saveToCache(filename, node); - } - node->setDefault(defaults_tree); - node->updateDefault(); - return true; - } - - node = nullptr; - return false; -} + U8* buffer = new U8[length+1]; + size_t nread = fread(buffer, 1, length, fp); + buffer[nread] = 0; + fclose(fp); -// static -bool LLXMLNode::parseBuffer( - const char* buffer, - U32 length, - LLXMLNodePtr& node, - LLXMLNode* defaults) -{ - if (parseBuffer(buffer, length, node)) - { - node->setDefault(defaults); - node->updateDefault(); - return true; - } - return false; + bool rv = parseBuffer(buffer, nread, node, defaults_tree); + delete [] buffer; + return rv; } // static bool LLXMLNode::parseBuffer( - const char* buffer, + U8* buffer, U32 length, - LLXMLNodePtr& node) + LLXMLNodePtr& node, + LLXMLNode* defaults) { // Init XML_Parser my_parser = XML_ParserCreate(NULL); @@ -741,7 +696,7 @@ bool LLXMLNode::parseBuffer( XML_SetUserData(my_parser, (void *)file_node_ptr); // Do the parsing - if (XML_Parse(my_parser, buffer, length, true) != XML_STATUS_OK) + if (XML_Parse(my_parser, (const char *)buffer, length, true) != XML_STATUS_OK) { LL_WARNS() << "Error parsing xml error code: " << XML_ErrorString(XML_GetErrorCode(my_parser)) @@ -762,6 +717,9 @@ bool LLXMLNode::parseBuffer( LLXMLNode *return_node = file_node->mChildren->map.begin()->second; + return_node->setDefault(defaults); + return_node->updateDefault(); + node = return_node; return true; } @@ -866,20 +824,18 @@ bool LLXMLNode::isFullyDefault() } // static -bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root, const std::vector& paths, bool cacheable) +bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root, + const std::vector& paths) { - if (paths.empty()) - { - return false; - } + if (paths.empty()) return false; std::string filename = paths.front(); if (filename.empty()) { return false; } - - if (!LLXMLNode::parseFile(filename, root, nullptr, cacheable)) + + if (!LLXMLNode::parseFile(filename, root, NULL)) { LL_WARNS() << "Problem reading UI description file: " << filename << LL_ENDL; return false; diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index e09c89c543..d5b8b36d86 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -121,39 +121,39 @@ public: LLXMLNode(const char* name, bool is_attribute); LLXMLNode(LLStringTableEntry* name, bool is_attribute); LLXMLNode(const LLXMLNode& rhs); - LLXMLNodePtr deepCopy() const; + LLXMLNodePtr deepCopy(); bool isNull(); bool deleteChild(LLXMLNode* child); - void addChild(LLXMLNodePtr& new_child); + void addChild(LLXMLNodePtr& new_child); void setParent(LLXMLNodePtr& new_parent); // reparent if necessary - // Deserialization + // Serialization static bool parseFile( const std::string& filename, - LLXMLNodePtr& node, - LLXMLNode* defaults_tree, - bool cacheable = false); - static bool parseBuffer( - const char* buffer, - U32 length, - LLXMLNodePtr& node, - LLXMLNode* defaults); + LLXMLNodePtr& node, + LLXMLNode* defaults_tree); + static bool parseBuffer( + U8* buffer, + U32 length, + LLXMLNodePtr& node, + LLXMLNode* defaults); static bool parseStream( std::istream& str, - LLXMLNodePtr& node, + LLXMLNodePtr& node, LLXMLNode* defaults); static bool updateNode( LLXMLNodePtr& node, LLXMLNodePtr& update_node); - - static bool getLayeredXMLNode(LLXMLNodePtr& root, const std::vector& paths, bool cacheable = false); - + + static bool getLayeredXMLNode(LLXMLNodePtr& root, const std::vector& paths); + + // Write standard XML file header: // static void writeHeaderToFile(LLFILE *out_file); - + // Write XML to file with one attribute per line. // XML escapes values as they are written. void writeToFile(LLFILE *out_file, const std::string& indent = std::string(), bool use_type_decorations=true); @@ -237,7 +237,7 @@ public: // Setters bool setAttributeString(const char* attr, const std::string& value); - + void setBoolValue(const bool value) { setBoolValue(1, &value); } void setByteValue(const U8 value, Encoding encoding = ENCODING_DEFAULT) { setByteValue(1, &value, encoding); } void setIntValue(const S32 value, Encoding encoding = ENCODING_DEFAULT) { setIntValue(1, &value, encoding); } @@ -290,10 +290,6 @@ public: protected: bool removeChild(LLXMLNode* child); - static bool parseBuffer( - const char* buffer, - U32 length, - LLXMLNodePtr& node); public: std::string mID; // The ID attribute of this node diff --git a/indra/llxml/llxmltree.cpp b/indra/llxml/llxmltree.cpp index 0c1615f486..a9c702f552 100644 --- a/indra/llxml/llxmltree.cpp +++ b/indra/llxml/llxmltree.cpp @@ -35,7 +35,6 @@ #include "v4math.h" #include "llquaternion.h" #include "lluuid.h" -#include "lldir.h" ////////////////////////////////////////////////////////////// // LLXmlTree @@ -61,37 +60,20 @@ void LLXmlTree::cleanup() mNodeNames.cleanup(); } -bool LLXmlTree::parseFile(const std::string & filename, bool keep_contents) -{ - delete mRoot; - mRoot = NULL; - - std::string xml = gDirUtilp->getFileContents(filename); - if (xml.empty()) - { - LL_WARNS() << "LLXmlTree parse failed. No XML file: " << filename << LL_ENDL; - return false; - } - - bool success = parseString(xml, keep_contents); - return success; -} - -bool LLXmlTree::parseString(const std::string &xml, bool keep_contents) +bool LLXmlTree::parseFile(const std::string &path, bool keep_contents) { delete mRoot; mRoot = NULL; LLXmlTreeParser parser(this); - bool success = parser.parseString(xml, &mRoot, keep_contents); - if (!success) + bool success = parser.parseFile( path, &mRoot, keep_contents ); + if( !success ) { S32 line_number = parser.getCurrentLineNumber(); const char* error = parser.getErrorString(); LL_WARNS() << "LLXmlTree parse failed. Line " << line_number << ": " << error << LL_ENDL; } - return success; } @@ -554,27 +536,6 @@ bool LLXmlTreeParser::parseFile(const std::string &path, LLXmlTreeNode** root, b return success; } -bool LLXmlTreeParser::parseString(const std::string& xml, LLXmlTreeNode** root, bool keep_contents) -{ - llassert( !mRoot ); - llassert( !mCurrent ); - - mKeepContents = keep_contents; - - bool success = LLXmlParser::parse(xml.data(), (int)xml.size(), true); - - *root = mRoot; - mRoot = NULL; - - if (success) - { - llassert(!mCurrent); - } - - mCurrent = NULL; - - return success; -} const std::string& LLXmlTreeParser::tabs() { diff --git a/indra/llxml/llxmltree.h b/indra/llxml/llxmltree.h index d47f26f731..5d15c4c7f5 100644 --- a/indra/llxml/llxmltree.h +++ b/indra/llxml/llxmltree.h @@ -56,7 +56,6 @@ public: void cleanup(); virtual bool parseFile(const std::string &path, bool keep_contents = true); - virtual bool parseString(const std::string &xml, bool keep_contents = true); LLXmlTreeNode* getRoot() { return mRoot; } @@ -200,8 +199,7 @@ public: LLXmlTreeParser(LLXmlTree* tree); virtual ~LLXmlTreeParser(); - bool parseFile(const std::string &path, LLXmlTreeNode** root, bool keep_contents); - bool parseString(const std::string &xml, LLXmlTreeNode** root, bool keep_contents); + bool parseFile(const std::string &path, LLXmlTreeNode** root, bool keep_contents ); protected: const std::string& tabs(); -- cgit v1.2.3