From 2b31dad40026d8078ea30d0da0656a4078d0f5b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20N=C3=A6sbye=20Christensen?= Date: Fri, 9 Feb 2024 22:26:02 +0100 Subject: miscellaneous: BOOL (int) to real bool --- indra/llxml/llcontrol.cpp | 2 +- indra/llxml/llcontrol.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index 2960ecf829..b53d573bae 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -508,7 +508,7 @@ LLControlVariable* LLControlGroup::declareF32(const std::string& name, const F32 return declareControl(name, TYPE_F32, initial_val, comment, persist); } -LLControlVariable* LLControlGroup::declareBOOL(const std::string& name, const BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist) +LLControlVariable* LLControlGroup::declareBOOL(const std::string& name, const bool initial_val, const std::string& comment, LLControlVariable::ePersist persist) { return declareControl(name, TYPE_BOOLEAN, initial_val, comment, persist); } diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 0839c02c50..d682b2c7c7 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -214,7 +214,7 @@ public: LLControlVariable* declareU32(const std::string& name, U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); LLControlVariable* declareS32(const std::string& name, S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); LLControlVariable* declareF32(const std::string& name, F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareBOOL(const std::string& name, bool initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); LLControlVariable* declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); LLControlVariable* declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); LLControlVariable* declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); -- cgit v1.2.3 From 70f8dc7a4f4be217fea5439e474fc75e567c23c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20N=C3=A6sbye=20Christensen?= Date: Sat, 10 Feb 2024 22:37:52 +0100 Subject: miscellaneous: BOOL (int) to real bool --- indra/llxml/llcontrol.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index b53d573bae..1abf6832fb 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -179,7 +179,7 @@ LLSD LLControlVariable::getComparableValue(const LLSD& value) if(TYPE_BOOLEAN == type() && value.isString()) { BOOL temp; - if(LLStringUtil::convertToBOOL(value.asString(), temp)) + if(LLStringUtil::convertToBOOL(value.asString(), temp)) { storable_value = (bool)temp; } -- cgit v1.2.3 From 9e854b697a06abed2a0917fb6120445f176764f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20N=C3=A6sbye=20Christensen?= Date: Fri, 16 Feb 2024 19:29:51 +0100 Subject: misc: BOOL to bool --- indra/llxml/llcontrol.cpp | 6 +++--- indra/llxml/llxmltree.cpp | 4 ++-- indra/llxml/llxmltree.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index 1abf6832fb..2c04147a5a 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -178,10 +178,10 @@ LLSD LLControlVariable::getComparableValue(const LLSD& value) LLSD storable_value; if(TYPE_BOOLEAN == type() && value.isString()) { - BOOL temp; + bool temp; if(LLStringUtil::convertToBOOL(value.asString(), temp)) { - storable_value = (bool)temp; + storable_value = temp; } else { @@ -859,7 +859,7 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require break; case TYPE_BOOLEAN: { - BOOL initial = FALSE; + bool initial = false; child_nodep->getAttributeBOOL("value", initial); control->set(initial); diff --git a/indra/llxml/llxmltree.cpp b/indra/llxml/llxmltree.cpp index ed9c07e1db..4991e99a96 100644 --- a/indra/llxml/llxmltree.cpp +++ b/indra/llxml/llxmltree.cpp @@ -199,7 +199,7 @@ void LLXmlTreeNode::addChild(LLXmlTreeNode* child) // These functions assume that name is already in mAttritrubteKeys -BOOL LLXmlTreeNode::getFastAttributeBOOL(LLStdStringHandle canonical_name, BOOL& value) +bool LLXmlTreeNode::getFastAttributeBOOL(LLStdStringHandle canonical_name, bool& value) { const std::string *s = getAttribute( canonical_name ); return s && LLStringUtil::convertToBOOL( *s, value ); @@ -310,7 +310,7 @@ BOOL LLXmlTreeNode::getFastAttributeString(LLStdStringHandle canonical_name, std ////////////////////////////////////////////////////////////// -BOOL LLXmlTreeNode::getAttributeBOOL(const std::string& name, BOOL& value) +bool LLXmlTreeNode::getAttributeBOOL(const std::string& name, bool& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeBOOL(canonical_name, value); diff --git a/indra/llxml/llxmltree.h b/indra/llxml/llxmltree.h index 3e425c3870..5d33e2c660 100644 --- a/indra/llxml/llxmltree.h +++ b/indra/llxml/llxmltree.h @@ -105,7 +105,7 @@ public: BOOL hasAttribute( const std::string& name ); // Fast versions use cannonical_name handlee to entru in LLXmlTree::sAttributeKeys string table - BOOL getFastAttributeBOOL( LLStdStringHandle cannonical_name, BOOL& value ); + bool getFastAttributeBOOL( LLStdStringHandle cannonical_name, bool& value ); BOOL getFastAttributeU8( LLStdStringHandle cannonical_name, U8& value ); BOOL getFastAttributeS8( LLStdStringHandle cannonical_name, S8& value ); BOOL getFastAttributeU16( LLStdStringHandle cannonical_name, U16& value ); @@ -124,7 +124,7 @@ public: BOOL getFastAttributeString( LLStdStringHandle cannonical_name, std::string& value ); // Normal versions find 'name' in LLXmlTree::sAttributeKeys then call fast versions - virtual BOOL getAttributeBOOL( const std::string& name, BOOL& value ); + virtual bool getAttributeBOOL( const std::string& name, bool& value ); virtual BOOL getAttributeU8( const std::string& name, U8& value ); virtual BOOL getAttributeS8( const std::string& name, S8& value ); virtual BOOL getAttributeU16( const std::string& name, U16& value ); -- cgit v1.2.3 From 088f2f4f6545ebc2ee01945938a40ae5c87ad27a Mon Sep 17 00:00:00 2001 From: Ansariel Date: Sat, 17 Feb 2024 00:51:13 +0100 Subject: More BOOL to bool replacements primarily in llappearance and llxml --- indra/llxml/llxmlnode.cpp | 265 +++++++++++++++++++++----------------------- indra/llxml/llxmlnode.h | 96 ++++++++-------- indra/llxml/llxmlparser.cpp | 14 +-- indra/llxml/llxmlparser.h | 2 +- indra/llxml/llxmltree.cpp | 98 ++++++++-------- indra/llxml/llxmltree.h | 76 ++++++------- 6 files changed, 265 insertions(+), 286 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 455df13e48..9c7ac66f01 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -44,13 +44,13 @@ #include "lldir.h" // static -BOOL LLXMLNode::sStripEscapedStrings = TRUE; -BOOL LLXMLNode::sStripWhitespaceValues = FALSE; +bool LLXMLNode::sStripEscapedStrings = true; +bool LLXMLNode::sStripWhitespaceValues = false; LLXMLNode::LLXMLNode() : mID(""), mParser(NULL), - mIsAttribute(FALSE), + mIsAttribute(false), mVersionMajor(0), mVersionMinor(0), mLength(0), @@ -69,7 +69,7 @@ LLXMLNode::LLXMLNode() : { } -LLXMLNode::LLXMLNode(const char* name, BOOL is_attribute) : +LLXMLNode::LLXMLNode(const char* name, bool is_attribute) : mID(""), mParser(NULL), mIsAttribute(is_attribute), @@ -91,7 +91,7 @@ LLXMLNode::LLXMLNode(const char* name, BOOL is_attribute) : mName = gStringTable.addStringEntry(name); } -LLXMLNode::LLXMLNode(LLStringTableEntry* name, BOOL is_attribute) : +LLXMLNode::LLXMLNode(LLStringTableEntry* name, bool is_attribute) : mID(""), mParser(NULL), mIsAttribute(is_attribute), @@ -193,17 +193,17 @@ LLXMLNode::~LLXMLNode() mDefault = NULL; } -BOOL LLXMLNode::isNull() +bool LLXMLNode::isNull() { return (mName == NULL); } // protected -BOOL LLXMLNode::removeChild(LLXMLNode *target_child) +bool LLXMLNode::removeChild(LLXMLNode *target_child) { if (!target_child) { - return FALSE; + return false; } if (target_child->mIsAttribute) { @@ -212,7 +212,7 @@ BOOL LLXMLNode::removeChild(LLXMLNode *target_child) { target_child->mParent = NULL; mAttributes.erase(children_itr); - return TRUE; + return true; } } else if (mChildren.notNull()) @@ -244,7 +244,7 @@ BOOL LLXMLNode::removeChild(LLXMLNode *target_child) { mChildren = NULL; } - return TRUE; + return true; } else if (children_itr->first != target_child->mName) { @@ -256,7 +256,7 @@ BOOL LLXMLNode::removeChild(LLXMLNode *target_child) } } } - return FALSE; + return false; } void LLXMLNode::addChild(LLXMLNodePtr& new_child) @@ -302,13 +302,13 @@ void LLXMLNode::addChild(LLXMLNodePtr& new_child) } // virtual -LLXMLNodePtr LLXMLNode::createChild(const char* name, BOOL is_attribute) +LLXMLNodePtr LLXMLNode::createChild(const char* name, bool is_attribute) { return createChild(gStringTable.addStringEntry(name), is_attribute); } // virtual -LLXMLNodePtr LLXMLNode::createChild(LLStringTableEntry* name, BOOL is_attribute) +LLXMLNodePtr LLXMLNode::createChild(LLStringTableEntry* name, bool is_attribute) { LLXMLNodePtr ret(new LLXMLNode(name, is_attribute)); ret->mID.clear(); @@ -317,13 +317,13 @@ LLXMLNodePtr LLXMLNode::createChild(LLStringTableEntry* name, BOOL is_attribute) return ret; } -BOOL LLXMLNode::deleteChild(LLXMLNode *child) +bool LLXMLNode::deleteChild(LLXMLNode *child) { if (removeChild(child)) { - return TRUE; + return true; } - return FALSE; + return false; } void LLXMLNode::setParent(LLXMLNodePtr& new_parent) @@ -375,7 +375,7 @@ void XMLCALL StartXMLNode(void *userData, const XML_Char **atts) { // Create a new node - LLXMLNode *new_node_ptr = new LLXMLNode(name, FALSE); + LLXMLNode *new_node_ptr = new LLXMLNode(name, false); LLXMLNodePtr new_node = new_node_ptr; new_node->mID.clear(); @@ -480,9 +480,9 @@ void XMLCALL StartXMLNode(void *userData, // only one attribute child per description LLXMLNodePtr attr_node; - if (!new_node->getAttribute(attr_name.c_str(), attr_node, FALSE)) + if (!new_node->getAttribute(attr_name.c_str(), attr_node, false)) { - attr_node = new LLXMLNode(attr_name.c_str(), TRUE); + attr_node = new LLXMLNode(attr_name.c_str(), true); attr_node->setLineNumber(XML_GetCurrentLineNumber(*new_node_ptr->mParser)); } attr_node->setValue(attr_value); @@ -508,13 +508,13 @@ void XMLCALL EndXMLNode(void *userData, if (LLXMLNode::sStripWhitespaceValues) { std::string value = node->getValue(); - BOOL is_empty = TRUE; + bool is_empty = true; for (std::string::size_type s = 0; s < value.length(); s++) { char c = value[s]; if (c != ' ' && c != '\t' && c != '\n') { - is_empty = FALSE; + is_empty = false; break; } } @@ -575,7 +575,7 @@ bool LLXMLNode::updateNode( if (!node || !update_node) { LL_WARNS() << "Node invalid" << LL_ENDL; - return FALSE; + return false; } //update the node value @@ -647,7 +647,7 @@ bool LLXMLNode::updateNode( } } - return TRUE; + return true; } // static @@ -688,7 +688,7 @@ bool LLXMLNode::parseBuffer( XML_SetCharacterDataHandler(my_parser, XMLData); // Create a root node - LLXMLNode *file_node_ptr = new LLXMLNode("XML", FALSE); + LLXMLNode *file_node_ptr = new LLXMLNode("XML", false); LLXMLNodePtr file_node = file_node_ptr; file_node->mParser = &my_parser; @@ -696,7 +696,7 @@ bool LLXMLNode::parseBuffer( XML_SetUserData(my_parser, (void *)file_node_ptr); // Do the parsing - if (XML_Parse(my_parser, (const char *)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)) @@ -736,7 +736,7 @@ bool LLXMLNode::parseStream( XML_SetCharacterDataHandler(my_parser, XMLData); // Create a root node - LLXMLNode *file_node_ptr = new LLXMLNode("XML", FALSE); + LLXMLNode *file_node_ptr = new LLXMLNode("XML", false); LLXMLNodePtr file_node = file_node_ptr; file_node->mParser = &my_parser; @@ -784,18 +784,18 @@ bool LLXMLNode::parseStream( } -BOOL LLXMLNode::isFullyDefault() +bool LLXMLNode::isFullyDefault() { if (mDefault.isNull()) { - return FALSE; + return false; } - BOOL has_default_value = (mValue == mDefault->mValue); - BOOL has_default_attribute = (mIsAttribute == mDefault->mIsAttribute); - BOOL has_default_type = mIsAttribute || (mType == mDefault->mType); - BOOL has_default_encoding = mIsAttribute || (mEncoding == mDefault->mEncoding); - BOOL has_default_precision = mIsAttribute || (mPrecision == mDefault->mPrecision); - BOOL has_default_length = mIsAttribute || (mLength == mDefault->mLength); + bool has_default_value = (mValue == mDefault->mValue); + bool has_default_attribute = (mIsAttribute == mDefault->mIsAttribute); + bool has_default_type = mIsAttribute || (mType == mDefault->mType); + bool has_default_encoding = mIsAttribute || (mEncoding == mDefault->mEncoding); + bool has_default_precision = mIsAttribute || (mPrecision == mDefault->mPrecision); + bool has_default_length = mIsAttribute || (mLength == mDefault->mLength); if (has_default_value && has_default_type @@ -813,14 +813,14 @@ BOOL LLXMLNode::isFullyDefault() LLXMLNodePtr child = (*children_itr).second; if (!child->isFullyDefault()) { - return FALSE; + return false; } } } - return TRUE; + return true; } - return FALSE; + return false; } // static @@ -908,10 +908,10 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i return; } - BOOL has_default_type = mDefault.isNull()?FALSE:(mType == mDefault->mType); - BOOL has_default_encoding = mDefault.isNull()?FALSE:(mEncoding == mDefault->mEncoding); - BOOL has_default_precision = mDefault.isNull()?FALSE:(mPrecision == mDefault->mPrecision); - BOOL has_default_length = mDefault.isNull()?FALSE:(mLength == mDefault->mLength); + bool has_default_type = mDefault.isNull()?false:(mType == mDefault->mType); + bool has_default_encoding = mDefault.isNull()?false:(mEncoding == mDefault->mEncoding); + bool has_default_precision = mDefault.isNull()?false:(mPrecision == mDefault->mPrecision); + bool has_default_length = mDefault.isNull()?false:(mLength == mDefault->mLength); // stream the name output_stream << indent << "<" << mName->mString << "\n"; @@ -1153,12 +1153,12 @@ void LLXMLNode::scrubToTree(LLXMLNode *tree) } } -bool LLXMLNode::getChild(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing) +bool LLXMLNode::getChild(const char* name, LLXMLNodePtr& node, bool use_default_if_missing) { return getChild(gStringTable.checkStringEntry(name), node, use_default_if_missing); } -bool LLXMLNode::getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing) +bool LLXMLNode::getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, bool use_default_if_missing) { if (mChildren.notNull()) { @@ -1171,18 +1171,18 @@ bool LLXMLNode::getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOO } if (use_default_if_missing && !mDefault.isNull()) { - return mDefault->getChild(name, node, FALSE); + return mDefault->getChild(name, node, false); } node = NULL; return false; } -void LLXMLNode::getChildren(const char* name, LLXMLNodeList &children, BOOL use_default_if_missing) const +void LLXMLNode::getChildren(const char* name, LLXMLNodeList &children, bool use_default_if_missing) const { getChildren(gStringTable.checkStringEntry(name), children, use_default_if_missing); } -void LLXMLNode::getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, BOOL use_default_if_missing) const +void LLXMLNode::getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, bool use_default_if_missing) const { if (mChildren.notNull()) { @@ -1204,7 +1204,7 @@ void LLXMLNode::getChildren(const LLStringTableEntry* name, LLXMLNodeList &child } if (children.size() == 0 && use_default_if_missing && !mDefault.isNull()) { - mDefault->getChildren(name, children, FALSE); + mDefault->getChildren(name, children, false); } } @@ -1227,12 +1227,12 @@ void LLXMLNode::getDescendants(const LLStringTableEntry* name, LLXMLNodeList &ch } } -bool LLXMLNode::getAttribute(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing) +bool LLXMLNode::getAttribute(const char* name, LLXMLNodePtr& node, bool use_default_if_missing) { return getAttribute(gStringTable.checkStringEntry(name), node, use_default_if_missing); } -bool LLXMLNode::getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing) +bool LLXMLNode::getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, bool use_default_if_missing) { LLXMLAttribList::const_iterator child_itr = mAttributes.find(name); if (child_itr != mAttributes.end()) @@ -1242,7 +1242,7 @@ bool LLXMLNode::getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, } if (use_default_if_missing && !mDefault.isNull()) { - return mDefault->getAttribute(name, node, FALSE); + return mDefault->getAttribute(name, node, false); } return false; @@ -1261,42 +1261,25 @@ bool LLXMLNode::setAttributeString(const char* attr, const std::string& value) return false; } -BOOL LLXMLNode::hasAttribute(const char* name ) +bool LLXMLNode::hasAttribute(const char* name ) { LLXMLNodePtr node; return getAttribute(name, node); } -// the structure of these getAttribute_ functions is ugly, but it's because the -// underlying system is based on BOOL and LLString; if we change -// so that they're based on more generic mechanisms, these will be -// simplified. -bool LLXMLNode::getAttribute_bool(const char* name, bool& value ) -{ - LLXMLNodePtr node; - if (!getAttribute(name, node)) - { - return false; - } - BOOL temp; - bool retval = node->getBoolValue(1, &temp); - value = temp; - return retval; -} - -BOOL LLXMLNode::getAttributeBOOL(const char* name, BOOL& value ) +bool LLXMLNode::getAttributeBOOL(const char* name, bool& value ) { LLXMLNodePtr node; return (getAttribute(name, node) && node->getBoolValue(1, &value)); } -BOOL LLXMLNode::getAttributeU8(const char* name, U8& value ) +bool LLXMLNode::getAttributeU8(const char* name, U8& value ) { LLXMLNodePtr node; return (getAttribute(name, node) && node->getByteValue(1, &value)); } -BOOL LLXMLNode::getAttributeS8(const char* name, S8& value ) +bool LLXMLNode::getAttributeS8(const char* name, S8& value ) { LLXMLNodePtr node; S32 val; @@ -1308,7 +1291,7 @@ BOOL LLXMLNode::getAttributeS8(const char* name, S8& value ) return true; } -BOOL LLXMLNode::getAttributeU16(const char* name, U16& value ) +bool LLXMLNode::getAttributeU16(const char* name, U16& value ) { LLXMLNodePtr node; U32 val; @@ -1320,7 +1303,7 @@ BOOL LLXMLNode::getAttributeU16(const char* name, U16& value ) return true; } -BOOL LLXMLNode::getAttributeS16(const char* name, S16& value ) +bool LLXMLNode::getAttributeS16(const char* name, S16& value ) { LLXMLNodePtr node; S32 val; @@ -1332,73 +1315,73 @@ BOOL LLXMLNode::getAttributeS16(const char* name, S16& value ) return true; } -BOOL LLXMLNode::getAttributeU32(const char* name, U32& value ) +bool LLXMLNode::getAttributeU32(const char* name, U32& value ) { LLXMLNodePtr node; return (getAttribute(name, node) && node->getUnsignedValue(1, &value)); } -BOOL LLXMLNode::getAttributeS32(const char* name, S32& value ) +bool LLXMLNode::getAttributeS32(const char* name, S32& value ) { LLXMLNodePtr node; return (getAttribute(name, node) && node->getIntValue(1, &value)); } -BOOL LLXMLNode::getAttributeF32(const char* name, F32& value ) +bool LLXMLNode::getAttributeF32(const char* name, F32& value ) { LLXMLNodePtr node; return (getAttribute(name, node) && node->getFloatValue(1, &value)); } -BOOL LLXMLNode::getAttributeF64(const char* name, F64& value ) +bool LLXMLNode::getAttributeF64(const char* name, F64& value ) { LLXMLNodePtr node; return (getAttribute(name, node) && node->getDoubleValue(1, &value)); } -BOOL LLXMLNode::getAttributeColor(const char* name, LLColor4& value ) +bool LLXMLNode::getAttributeColor(const char* name, LLColor4& value ) { LLXMLNodePtr node; return (getAttribute(name, node) && node->getFloatValue(4, value.mV)); } -BOOL LLXMLNode::getAttributeColor4(const char* name, LLColor4& value ) +bool LLXMLNode::getAttributeColor4(const char* name, LLColor4& value ) { LLXMLNodePtr node; return (getAttribute(name, node) && node->getFloatValue(4, value.mV)); } -BOOL LLXMLNode::getAttributeColor4U(const char* name, LLColor4U& value ) +bool LLXMLNode::getAttributeColor4U(const char* name, LLColor4U& value ) { LLXMLNodePtr node; return (getAttribute(name, node) && node->getByteValue(4, value.mV)); } -BOOL LLXMLNode::getAttributeVector3(const char* name, LLVector3& value ) +bool LLXMLNode::getAttributeVector3(const char* name, LLVector3& value ) { LLXMLNodePtr node; return (getAttribute(name, node) && node->getFloatValue(3, value.mV)); } -BOOL LLXMLNode::getAttributeVector3d(const char* name, LLVector3d& value ) +bool LLXMLNode::getAttributeVector3d(const char* name, LLVector3d& value ) { LLXMLNodePtr node; return (getAttribute(name, node) && node->getDoubleValue(3, value.mdV)); } -BOOL LLXMLNode::getAttributeQuat(const char* name, LLQuaternion& value ) +bool LLXMLNode::getAttributeQuat(const char* name, LLQuaternion& value ) { LLXMLNodePtr node; return (getAttribute(name, node) && node->getFloatValue(4, value.mQ)); } -BOOL LLXMLNode::getAttributeUUID(const char* name, LLUUID& value ) +bool LLXMLNode::getAttributeUUID(const char* name, LLUUID& value ) { LLXMLNodePtr node; return (getAttribute(name, node) && node->getUUIDValue(1, &value)); } -BOOL LLXMLNode::getAttributeString(const char* name, std::string& value ) +bool LLXMLNode::getAttributeString(const char* name, std::string& value ) { LLXMLNodePtr node; if (!getAttribute(name, node)) @@ -1435,10 +1418,10 @@ const char *LLXMLNode::skipNonWhitespace(const char *str) } /*static */ -const char *LLXMLNode::parseInteger(const char *str, U64 *dest, BOOL *is_negative, U32 precision, Encoding encoding) +const char *LLXMLNode::parseInteger(const char *str, U64 *dest, bool *is_negative, U32 precision, Encoding encoding) { *dest = 0; - *is_negative = FALSE; + *is_negative = false; str = skipWhitespace(str); @@ -1452,7 +1435,7 @@ const char *LLXMLNode::parseInteger(const char *str, U64 *dest, BOOL *is_negativ } if (str[0] == '-') { - *is_negative = TRUE; + *is_negative = true; ++str; } @@ -1653,7 +1636,7 @@ const char *LLXMLNode::parseFloat(const char *str, F64 *dest, U32 precision, Enc // Scientific notation! ++str; U64 exp; - BOOL is_negative; + bool is_negative; str = parseInteger(str, &exp, &is_negative, 64, ENCODING_DECIMAL); if (str == NULL) { @@ -1677,7 +1660,7 @@ const char *LLXMLNode::parseFloat(const char *str, F64 *dest, U32 precision, Enc if (encoding == ENCODING_HEX) { U64 bytes_dest; - BOOL is_negative; + bool is_negative; str = parseInteger(str, (U64 *)&bytes_dest, &is_negative, precision, ENCODING_HEX); // Upcast to F64 switch (precision) @@ -1700,7 +1683,7 @@ const char *LLXMLNode::parseFloat(const char *str, F64 *dest, U32 precision, Enc return NULL; } -U32 LLXMLNode::getBoolValue(U32 expected_length, BOOL *array) +U32 LLXMLNode::getBoolValue(U32 expected_length, bool *array) { llassert(array); @@ -1720,11 +1703,11 @@ U32 LLXMLNode::getBoolValue(U32 expected_length, BOOL *array) LLStringUtil::toLower(str_array[i]); if (str_array[i] == "false") { - array[ret_length++] = FALSE; + array[ret_length++] = false; } else if (str_array[i] == "true") { - array[ret_length++] = TRUE; + array[ret_length++] = true; } } @@ -1770,7 +1753,7 @@ U32 LLXMLNode::getByteValue(U32 expected_length, U8 *array, Encoding encoding) for (i=0; i 0 ? TRUE : FALSE; + return removed_count > 0; } -BOOL LLXMLNode::deleteChildren(LLStringTableEntry* name) +bool LLXMLNode::deleteChildren(LLStringTableEntry* name) { U32 removed_count = 0; LLXMLNodeList node_list; @@ -2655,7 +2638,7 @@ BOOL LLXMLNode::deleteChildren(LLStringTableEntry* name) } } } - return removed_count > 0 ? TRUE : FALSE; + return removed_count > 0; } void LLXMLNode::setAttributes(LLXMLNode::ValueType type, U32 precision, LLXMLNode::Encoding encoding, U32 length) @@ -2778,7 +2761,7 @@ void LLXMLNode::createUnitTest(S32 max_num_children) child_name.append(1, c); } - LLXMLNode *new_child = createChild(child_name.c_str(), FALSE); + LLXMLNode *new_child = createChild(child_name.c_str(), false); // Random ID std::string child_id; @@ -2805,7 +2788,7 @@ void LLXMLNode::createUnitTest(S32 max_num_children) break; case 1: // TYPE_BOOLEAN { - BOOL random_bool_values[30]; + bool random_bool_values[30]; for (U32 value=0; valuesetUnsignedValue(1, &integer_checksum, LLXMLNode::ENCODING_HEX); - createChild("long_checksum", TRUE)->setLongValue(1, &long_checksum, LLXMLNode::ENCODING_HEX); - createChild("bool_true_count", TRUE)->setUnsignedValue(1, &bool_true_count, LLXMLNode::ENCODING_HEX); - createChild("uuid_checksum", TRUE)->setUUIDValue(1, &uuid_checksum); - createChild("noderef_checksum", TRUE)->setUnsignedValue(1, &noderef_checksum, LLXMLNode::ENCODING_HEX); - createChild("float_checksum", TRUE)->setUnsignedValue(1, &float_checksum, LLXMLNode::ENCODING_HEX); + createChild("integer_checksum", true)->setUnsignedValue(1, &integer_checksum, LLXMLNode::ENCODING_HEX); + createChild("long_checksum", true)->setLongValue(1, &long_checksum, LLXMLNode::ENCODING_HEX); + createChild("bool_true_count", true)->setUnsignedValue(1, &bool_true_count, LLXMLNode::ENCODING_HEX); + createChild("uuid_checksum", true)->setUUIDValue(1, &uuid_checksum); + createChild("noderef_checksum", true)->setUnsignedValue(1, &noderef_checksum, LLXMLNode::ENCODING_HEX); + createChild("float_checksum", true)->setUnsignedValue(1, &float_checksum, LLXMLNode::ENCODING_HEX); } -BOOL LLXMLNode::performUnitTest(std::string &error_buffer) +bool LLXMLNode::performUnitTest(std::string &error_buffer) { if (mChildren.isNull()) { error_buffer.append(llformat("ERROR Node %s: No children found.\n", mName->mString)); - return FALSE; + return false; } // Checksums @@ -2950,14 +2933,14 @@ BOOL LLXMLNode::performUnitTest(std::string &error_buffer) if (!node->performUnitTest(error_buffer)) { error_buffer.append(llformat("Child test failed for %s.\n", mName->mString)); - //return FALSE; + //return false; } continue; } if (node->mLength < 1 || node->mLength > 30) { error_buffer.append(llformat("ERROR Node %s: Invalid array length %d, child %s.\n", mName->mString, node->mLength, node->mName->mString)); - return FALSE; + return false; } switch (node->mType) { @@ -2966,11 +2949,11 @@ BOOL LLXMLNode::performUnitTest(std::string &error_buffer) break; case TYPE_BOOLEAN: { - BOOL bool_array[30]; + bool bool_array[30]; if (node->getBoolValue(node->mLength, bool_array) < node->mLength) { error_buffer.append(llformat("ERROR Node %s: Could not read boolean array, child %s.\n", mName->mString, node->mName->mString)); - return FALSE; + return false; } for (U32 pos=0; pos<(U32)node->mLength; ++pos) { @@ -2989,7 +2972,7 @@ BOOL LLXMLNode::performUnitTest(std::string &error_buffer) if (node->getUnsignedValue(node->mLength, integer_array, node->mEncoding) < node->mLength) { error_buffer.append(llformat("ERROR Node %s: Could not read integer array, child %s.\n", mName->mString, node->mName->mString)); - return FALSE; + return false; } for (U32 pos=0; pos<(U32)node->mLength; ++pos) { @@ -3002,7 +2985,7 @@ BOOL LLXMLNode::performUnitTest(std::string &error_buffer) if (node->getLongValue(node->mLength, integer_array, node->mEncoding) < node->mLength) { error_buffer.append(llformat("ERROR Node %s: Could not read long integer array, child %s.\n", mName->mString, node->mName->mString)); - return FALSE; + return false; } for (U32 pos=0; pos<(U32)node->mLength; ++pos) { @@ -3019,7 +3002,7 @@ BOOL LLXMLNode::performUnitTest(std::string &error_buffer) if (node->getFloatValue(node->mLength, float_array, node->mEncoding) < node->mLength) { error_buffer.append(llformat("ERROR Node %s: Could not read float array, child %s.\n", mName->mString, node->mName->mString)); - return FALSE; + return false; } for (U32 pos=0; pos<(U32)node->mLength; ++pos) { @@ -3033,7 +3016,7 @@ BOOL LLXMLNode::performUnitTest(std::string &error_buffer) if (node->getDoubleValue(node->mLength, float_array, node->mEncoding) < node->mLength) { error_buffer.append(llformat("ERROR Node %s: Could not read float array, child %s.\n", mName->mString, node->mName->mString)); - return FALSE; + return false; } for (U32 pos=0; pos<(U32)node->mLength; ++pos) { @@ -3051,7 +3034,7 @@ BOOL LLXMLNode::performUnitTest(std::string &error_buffer) if (node->getUUIDValue(node->mLength, uuid_array) < node->mLength) { error_buffer.append(llformat("ERROR Node %s: Could not read uuid array, child %s.\n", mName->mString, node->mName->mString)); - return FALSE; + return false; } for (U32 pos=0; pos<(U32)node->mLength; ++pos) { @@ -3068,7 +3051,7 @@ BOOL LLXMLNode::performUnitTest(std::string &error_buffer) if (node->getNodeRefValue(node->mLength, node_array) < node->mLength) { error_buffer.append(llformat("ERROR Node %s: Could not read node ref array, child %s.\n", mName->mString, node->mName->mString)); - return FALSE; + return false; } for (U32 pos=0; posmLength; ++pos) { @@ -3089,97 +3072,97 @@ BOOL LLXMLNode::performUnitTest(std::string &error_buffer) // Compare checksums { U32 node_integer_checksum = 0; - if (!getAttribute("integer_checksum", checksum_node, FALSE) || + if (!getAttribute("integer_checksum", checksum_node, false) || checksum_node->getUnsignedValue(1, &node_integer_checksum, ENCODING_HEX) != 1) { error_buffer.append(llformat("ERROR Node %s: Integer checksum missing.\n", mName->mString)); - return FALSE; + return false; } if (node_integer_checksum != integer_checksum) { error_buffer.append(llformat("ERROR Node %s: Integer checksum mismatch: read %X / calc %X.\n", mName->mString, node_integer_checksum, integer_checksum)); - return FALSE; + return false; } } { U64 node_long_checksum = 0; - if (!getAttribute("long_checksum", checksum_node, FALSE) || + if (!getAttribute("long_checksum", checksum_node, false) || checksum_node->getLongValue(1, &node_long_checksum, ENCODING_HEX) != 1) { error_buffer.append(llformat("ERROR Node %s: Long Integer checksum missing.\n", mName->mString)); - return FALSE; + return false; } if (node_long_checksum != long_checksum) { U32 *pp1 = (U32 *)&node_long_checksum; U32 *pp2 = (U32 *)&long_checksum; error_buffer.append(llformat("ERROR Node %s: Long Integer checksum mismatch: read %08X%08X / calc %08X%08X.\n", mName->mString, pp1[1], pp1[0], pp2[1], pp2[0])); - return FALSE; + return false; } } { U32 node_bool_true_count = 0; - if (!getAttribute("bool_true_count", checksum_node, FALSE) || + if (!getAttribute("bool_true_count", checksum_node, false) || checksum_node->getUnsignedValue(1, &node_bool_true_count, ENCODING_HEX) != 1) { error_buffer.append(llformat("ERROR Node %s: Boolean checksum missing.\n", mName->mString)); - return FALSE; + return false; } if (node_bool_true_count != bool_true_count) { error_buffer.append(llformat("ERROR Node %s: Boolean checksum mismatch: read %X / calc %X.\n", mName->mString, node_bool_true_count, bool_true_count)); - return FALSE; + return false; } } { LLUUID node_uuid_checksum; - if (!getAttribute("uuid_checksum", checksum_node, FALSE) || + if (!getAttribute("uuid_checksum", checksum_node, false) || checksum_node->getUUIDValue(1, &node_uuid_checksum) != 1) { error_buffer.append(llformat("ERROR Node %s: UUID checksum missing.\n", mName->mString)); - return FALSE; + return false; } if (node_uuid_checksum != uuid_checksum) { error_buffer.append(llformat("ERROR Node %s: UUID checksum mismatch: read %s / calc %s.\n", mName->mString, node_uuid_checksum.asString().c_str(), uuid_checksum.asString().c_str())); - return FALSE; + return false; } } { U32 node_noderef_checksum = 0; - if (!getAttribute("noderef_checksum", checksum_node, FALSE) || + if (!getAttribute("noderef_checksum", checksum_node, false) || checksum_node->getUnsignedValue(1, &node_noderef_checksum, ENCODING_HEX) != 1) { error_buffer.append(llformat("ERROR Node %s: Node Ref checksum missing.\n", mName->mString)); - return FALSE; + return false; } if (node_noderef_checksum != noderef_checksum) { error_buffer.append(llformat("ERROR Node %s: Node Ref checksum mismatch: read %X / calc %X.\n", mName->mString, node_noderef_checksum, noderef_checksum)); - return FALSE; + return false; } } { U32 node_float_checksum = 0; - if (!getAttribute("float_checksum", checksum_node, FALSE) || + if (!getAttribute("float_checksum", checksum_node, false) || checksum_node->getUnsignedValue(1, &node_float_checksum, ENCODING_HEX) != 1) { error_buffer.append(llformat("ERROR Node %s: Float checksum missing.\n", mName->mString)); - return FALSE; + return false; } if (node_float_checksum != float_checksum) { error_buffer.append(llformat("ERROR Node %s: Float checksum mismatch: read %X / calc %X.\n", mName->mString, node_float_checksum, float_checksum)); - return FALSE; + return false; } } - return TRUE; + return true; } LLXMLNodePtr LLXMLNode::getFirstChild() const diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index 0b8da5dc5d..21a7dee4cc 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -57,9 +57,9 @@ struct CompareAttributes bool operator()(const LLStringTableEntry* const lhs, const LLStringTableEntry* const rhs) const { if (lhs == NULL) - return TRUE; + return true; if (rhs == NULL) - return FALSE; + return true; return strcmp(lhs->mString, rhs->mString) < 0; } @@ -118,14 +118,14 @@ protected: public: LLXMLNode(); - LLXMLNode(const char* name, BOOL is_attribute); - LLXMLNode(LLStringTableEntry* name, BOOL is_attribute); + LLXMLNode(const char* name, bool is_attribute); + LLXMLNode(LLStringTableEntry* name, bool is_attribute); LLXMLNode(const LLXMLNode& rhs); LLXMLNodePtr deepCopy(); - BOOL isNull(); + bool isNull(); - BOOL deleteChild(LLXMLNode* child); + bool deleteChild(LLXMLNode* child); void addChild(LLXMLNodePtr& new_child); void setParent(LLXMLNodePtr& new_parent); // reparent if necessary @@ -165,12 +165,12 @@ public: void findID(const std::string& id, LLXMLNodeList &results); - virtual LLXMLNodePtr createChild(const char* name, BOOL is_attribute); - virtual LLXMLNodePtr createChild(LLStringTableEntry* name, BOOL is_attribute); + virtual LLXMLNodePtr createChild(const char* name, bool is_attribute); + virtual LLXMLNodePtr createChild(LLStringTableEntry* name, bool is_attribute); // Getters - U32 getBoolValue(U32 expected_length, BOOL *array); + U32 getBoolValue(U32 expected_length, bool *array); U32 getByteValue(U32 expected_length, U8 *array, Encoding encoding = ENCODING_DEFAULT); U32 getIntValue(U32 expected_length, S32 *array, Encoding encoding = ENCODING_DEFAULT); U32 getUnsignedValue(U32 expected_length, U32 *array, Encoding encoding = ENCODING_DEFAULT); @@ -181,29 +181,25 @@ public: U32 getUUIDValue(U32 expected_length, LLUUID *array); U32 getNodeRefValue(U32 expected_length, LLXMLNode **array); - BOOL hasAttribute(const char* name ); - - // these are designed to be more generic versions of the functions - // rather than relying on LL-types - bool getAttribute_bool(const char* name, bool& value ); - - BOOL getAttributeBOOL(const char* name, BOOL& value ); - BOOL getAttributeU8(const char* name, U8& value ); - BOOL getAttributeS8(const char* name, S8& value ); - BOOL getAttributeU16(const char* name, U16& value ); - BOOL getAttributeS16(const char* name, S16& value ); - BOOL getAttributeU32(const char* name, U32& value ); - BOOL getAttributeS32(const char* name, S32& value ); - BOOL getAttributeF32(const char* name, F32& value ); - BOOL getAttributeF64(const char* name, F64& value ); - BOOL getAttributeColor(const char* name, LLColor4& value ); - BOOL getAttributeColor4(const char* name, LLColor4& value ); - BOOL getAttributeColor4U(const char* name, LLColor4U& value ); - BOOL getAttributeVector3(const char* name, LLVector3& value ); - BOOL getAttributeVector3d(const char* name, LLVector3d& value ); - BOOL getAttributeQuat(const char* name, LLQuaternion& value ); - BOOL getAttributeUUID(const char* name, LLUUID& value ); - BOOL getAttributeString(const char* name, std::string& value ); + bool hasAttribute(const char* name ); + + bool getAttributeBOOL(const char* name, bool& value ); + bool getAttributeU8(const char* name, U8& value ); + bool getAttributeS8(const char* name, S8& value ); + bool getAttributeU16(const char* name, U16& value ); + bool getAttributeS16(const char* name, S16& value ); + bool getAttributeU32(const char* name, U32& value ); + bool getAttributeS32(const char* name, S32& value ); + bool getAttributeF32(const char* name, F32& value ); + bool getAttributeF64(const char* name, F64& value ); + bool getAttributeColor(const char* name, LLColor4& value ); + bool getAttributeColor4(const char* name, LLColor4& value ); + bool getAttributeColor4U(const char* name, LLColor4U& value ); + bool getAttributeVector3(const char* name, LLVector3& value ); + bool getAttributeVector3d(const char* name, LLVector3d& value ); + bool getAttributeQuat(const char* name, LLQuaternion& value ); + bool getAttributeUUID(const char* name, LLUUID& value ); + bool getAttributeString(const char* name, std::string& value ); const ValueType& getType() const { return mType; } U32 getLength() const { return mLength; } @@ -212,23 +208,23 @@ public: std::string getSanitizedValue() const; std::string getTextContents() const; const LLStringTableEntry* getName() const { return mName; } - BOOL hasName(const char* name) const { return mName == gStringTable.checkStringEntry(name); } - BOOL hasName(const std::string& name) const { return mName == gStringTable.checkStringEntry(name.c_str()); } + bool hasName(const char* name) const { return mName == gStringTable.checkStringEntry(name); } + bool hasName(const std::string& name) const { return mName == gStringTable.checkStringEntry(name.c_str()); } const std::string& getID() const { return mID; } U32 getChildCount() const; // getChild returns a Null LLXMLNode (not a NULL pointer) if there is no such child. // This child has no value so any getTYPEValue() calls on it will return 0. - bool getChild(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE); - bool getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE); - void getChildren(const char* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const; - void getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const; + bool getChild(const char* name, LLXMLNodePtr& node, bool use_default_if_missing = true); + bool getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, bool use_default_if_missing = true); + void getChildren(const char* name, LLXMLNodeList &children, bool use_default_if_missing = true) const; + void getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, bool use_default_if_missing = true) const; // recursively finds all children at any level matching name void getDescendants(const LLStringTableEntry* name, LLXMLNodeList &children) const; - bool getAttribute(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE); - bool getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE); + bool getAttribute(const char* name, LLXMLNodePtr& node, bool use_default_if_missing = true); + bool getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, bool use_default_if_missing = true); S32 getLineNumber(); @@ -242,7 +238,7 @@ public: bool setAttributeString(const char* attr, const std::string& value); - void setBoolValue(const BOOL value) { setBoolValue(1, &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); } void setUnsignedValue(const U32 value, Encoding encoding = ENCODING_DEFAULT) { setUnsignedValue(1, &value, encoding); } @@ -253,7 +249,7 @@ public: void setUUIDValue(const LLUUID value) { setUUIDValue(1, &value); } void setNodeRefValue(const LLXMLNode *value) { setNodeRefValue(1, &value); } - void setBoolValue(U32 length, const BOOL *array); + void setBoolValue(U32 length, const bool *array); void setByteValue(U32 length, const U8 *array, Encoding encoding = ENCODING_DEFAULT); void setIntValue(U32 length, const S32 *array, Encoding encoding = ENCODING_DEFAULT); void setUnsignedValue(U32 length, const U32* array, Encoding encoding = ENCODING_DEFAULT); @@ -283,17 +279,17 @@ public: // Delete any child nodes that aren't among the tree's children, recursive void scrubToTree(LLXMLNode *tree); - BOOL deleteChildren(const std::string& name); - BOOL deleteChildren(LLStringTableEntry* name); + bool deleteChildren(const std::string& name); + bool deleteChildren(LLStringTableEntry* name); void setAttributes(ValueType type, U32 precision, Encoding encoding, U32 length); // void appendValue(const std::string& value); // Unused // Unit Testing void createUnitTest(S32 max_num_children); - BOOL performUnitTest(std::string &error_buffer); + bool performUnitTest(std::string &error_buffer); protected: - BOOL removeChild(LLXMLNode* child); + bool removeChild(LLXMLNode* child); public: std::string mID; // The ID attribute of this node @@ -315,8 +311,8 @@ public: LLXMLNodePtr mPrev; // Double-linked list previous node LLXMLNodePtr mNext; // Double-linked list next node - static BOOL sStripEscapedStrings; - static BOOL sStripWhitespaceValues; + static bool sStripEscapedStrings; + static bool sStripWhitespaceValues; protected: LLStringTableEntry *mName; // The name of this node @@ -330,10 +326,10 @@ protected: static const char *skipWhitespace(const char *str); static const char *skipNonWhitespace(const char *str); - static const char *parseInteger(const char *str, U64 *dest, BOOL *is_negative, U32 precision, Encoding encoding); + static const char *parseInteger(const char *str, U64 *dest, bool *is_negative, U32 precision, Encoding encoding); static const char *parseFloat(const char *str, F64 *dest, U32 precision, Encoding encoding); - BOOL isFullyDefault(); + bool isFullyDefault(); }; #endif // LL_LLXMLNODE diff --git a/indra/llxml/llxmlparser.cpp b/indra/llxml/llxmlparser.cpp index 1bdc283f67..f4116626f6 100644 --- a/indra/llxml/llxmlparser.cpp +++ b/indra/llxml/llxmlparser.cpp @@ -66,17 +66,17 @@ LLXmlParser::~LLXmlParser() } -BOOL LLXmlParser::parseFile(const std::string &path) +bool LLXmlParser::parseFile(const std::string &path) { llassert( !mDepth ); - BOOL success = TRUE; + bool success = true; LLFILE* file = LLFile::fopen(path, "rb"); /* Flawfinder: ignore */ if( !file ) { mAuxErrorString = llformat( "Couldn't open file %s", path.c_str()); - success = FALSE; + success = false; } else { @@ -90,7 +90,7 @@ BOOL LLXmlParser::parseFile(const std::string &path) if( !buffer ) { mAuxErrorString = llformat( "Unable to allocate XML buffer while reading file %s", path.c_str() ); - success = FALSE; + success = false; goto exit_label; } @@ -98,14 +98,14 @@ BOOL LLXmlParser::parseFile(const std::string &path) if( bytes_read <= 0 ) { mAuxErrorString = llformat( "Error while reading file %s", path.c_str() ); - success = FALSE; + success = false; goto exit_label; } - if( !XML_ParseBuffer(mParser, bytes_read, TRUE ) ) + if( !XML_ParseBuffer(mParser, bytes_read, true ) ) { mAuxErrorString = llformat( "Error while parsing file %s", path.c_str() ); - success = FALSE; + success = false; } exit_label: diff --git a/indra/llxml/llxmlparser.h b/indra/llxml/llxmlparser.h index a5b210404f..c5025ef450 100644 --- a/indra/llxml/llxmlparser.h +++ b/indra/llxml/llxmlparser.h @@ -43,7 +43,7 @@ public: virtual ~LLXmlParser(); // Parses entire file - BOOL parseFile(const std::string &path); + bool parseFile(const std::string &path); // Parses some input. Returns 0 if a fatal error is detected. // The last call must have isFinal true; diff --git a/indra/llxml/llxmltree.cpp b/indra/llxml/llxmltree.cpp index 4991e99a96..be3bcf2a66 100644 --- a/indra/llxml/llxmltree.cpp +++ b/indra/llxml/llxmltree.cpp @@ -61,13 +61,13 @@ void LLXmlTree::cleanup() } -BOOL LLXmlTree::parseFile(const std::string &path, BOOL keep_contents) +bool LLXmlTree::parseFile(const std::string &path, bool keep_contents) { delete mRoot; mRoot = NULL; LLXmlTreeParser parser(this); - BOOL success = parser.parseFile( path, &mRoot, keep_contents ); + bool success = parser.parseFile( path, &mRoot, keep_contents ); if( !success ) { S32 line_number = parser.getCurrentLineNumber(); @@ -135,7 +135,7 @@ void LLXmlTreeNode::dump( const std::string& prefix ) LL_CONT << LL_ENDL; } -BOOL LLXmlTreeNode::hasAttribute(const std::string& name) +bool LLXmlTreeNode::hasAttribute(const std::string& name) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); attribute_map_t::iterator iter = mAttributes.find(canonical_name); @@ -205,106 +205,106 @@ bool LLXmlTreeNode::getFastAttributeBOOL(LLStdStringHandle canonical_name, bool& return s && LLStringUtil::convertToBOOL( *s, value ); } -BOOL LLXmlTreeNode::getFastAttributeU8(LLStdStringHandle canonical_name, U8& value) +bool LLXmlTreeNode::getFastAttributeU8(LLStdStringHandle canonical_name, U8& value) { const std::string *s = getAttribute( canonical_name ); return s && LLStringUtil::convertToU8( *s, value ); } -BOOL LLXmlTreeNode::getFastAttributeS8(LLStdStringHandle canonical_name, S8& value) +bool LLXmlTreeNode::getFastAttributeS8(LLStdStringHandle canonical_name, S8& value) { const std::string *s = getAttribute( canonical_name ); return s && LLStringUtil::convertToS8( *s, value ); } -BOOL LLXmlTreeNode::getFastAttributeS16(LLStdStringHandle canonical_name, S16& value) +bool LLXmlTreeNode::getFastAttributeS16(LLStdStringHandle canonical_name, S16& value) { const std::string *s = getAttribute( canonical_name ); return s && LLStringUtil::convertToS16( *s, value ); } -BOOL LLXmlTreeNode::getFastAttributeU16(LLStdStringHandle canonical_name, U16& value) +bool LLXmlTreeNode::getFastAttributeU16(LLStdStringHandle canonical_name, U16& value) { const std::string *s = getAttribute( canonical_name ); return s && LLStringUtil::convertToU16( *s, value ); } -BOOL LLXmlTreeNode::getFastAttributeU32(LLStdStringHandle canonical_name, U32& value) +bool LLXmlTreeNode::getFastAttributeU32(LLStdStringHandle canonical_name, U32& value) { const std::string *s = getAttribute( canonical_name ); return s && LLStringUtil::convertToU32( *s, value ); } -BOOL LLXmlTreeNode::getFastAttributeS32(LLStdStringHandle canonical_name, S32& value) +bool LLXmlTreeNode::getFastAttributeS32(LLStdStringHandle canonical_name, S32& value) { const std::string *s = getAttribute( canonical_name ); return s && LLStringUtil::convertToS32( *s, value ); } -BOOL LLXmlTreeNode::getFastAttributeF32(LLStdStringHandle canonical_name, F32& value) +bool LLXmlTreeNode::getFastAttributeF32(LLStdStringHandle canonical_name, F32& value) { const std::string *s = getAttribute( canonical_name ); return s && LLStringUtil::convertToF32( *s, value ); } -BOOL LLXmlTreeNode::getFastAttributeF64(LLStdStringHandle canonical_name, F64& value) +bool LLXmlTreeNode::getFastAttributeF64(LLStdStringHandle canonical_name, F64& value) { const std::string *s = getAttribute( canonical_name ); return s && LLStringUtil::convertToF64( *s, value ); } -BOOL LLXmlTreeNode::getFastAttributeColor(LLStdStringHandle canonical_name, LLColor4& value) +bool LLXmlTreeNode::getFastAttributeColor(LLStdStringHandle canonical_name, LLColor4& value) { const std::string *s = getAttribute( canonical_name ); - return s ? LLColor4::parseColor(*s, &value) : FALSE; + return s ? LLColor4::parseColor(*s, &value) : false; } -BOOL LLXmlTreeNode::getFastAttributeColor4(LLStdStringHandle canonical_name, LLColor4& value) +bool LLXmlTreeNode::getFastAttributeColor4(LLStdStringHandle canonical_name, LLColor4& value) { const std::string *s = getAttribute( canonical_name ); - return s ? LLColor4::parseColor4(*s, &value) : FALSE; + return s ? LLColor4::parseColor4(*s, &value) : false; } -BOOL LLXmlTreeNode::getFastAttributeColor4U(LLStdStringHandle canonical_name, LLColor4U& value) +bool LLXmlTreeNode::getFastAttributeColor4U(LLStdStringHandle canonical_name, LLColor4U& value) { const std::string *s = getAttribute( canonical_name ); - return s ? LLColor4U::parseColor4U(*s, &value ) : FALSE; + return s ? LLColor4U::parseColor4U(*s, &value ) : false; } -BOOL LLXmlTreeNode::getFastAttributeVector3(LLStdStringHandle canonical_name, LLVector3& value) +bool LLXmlTreeNode::getFastAttributeVector3(LLStdStringHandle canonical_name, LLVector3& value) { const std::string *s = getAttribute( canonical_name ); - return s ? LLVector3::parseVector3(*s, &value ) : FALSE; + return s ? LLVector3::parseVector3(*s, &value ) : false; } -BOOL LLXmlTreeNode::getFastAttributeVector3d(LLStdStringHandle canonical_name, LLVector3d& value) +bool LLXmlTreeNode::getFastAttributeVector3d(LLStdStringHandle canonical_name, LLVector3d& value) { const std::string *s = getAttribute( canonical_name ); - return s ? LLVector3d::parseVector3d(*s, &value ) : FALSE; + return s ? LLVector3d::parseVector3d(*s, &value ) : false; } -BOOL LLXmlTreeNode::getFastAttributeQuat(LLStdStringHandle canonical_name, LLQuaternion& value) +bool LLXmlTreeNode::getFastAttributeQuat(LLStdStringHandle canonical_name, LLQuaternion& value) { const std::string *s = getAttribute( canonical_name ); - return s ? LLQuaternion::parseQuat(*s, &value ) : FALSE; + return s ? LLQuaternion::parseQuat(*s, &value ) : false; } -BOOL LLXmlTreeNode::getFastAttributeUUID(LLStdStringHandle canonical_name, LLUUID& value) +bool LLXmlTreeNode::getFastAttributeUUID(LLStdStringHandle canonical_name, LLUUID& value) { const std::string *s = getAttribute( canonical_name ); - return s ? LLUUID::parseUUID(*s, &value ) : FALSE; + return s ? LLUUID::parseUUID(*s, &value ) : false; } -BOOL LLXmlTreeNode::getFastAttributeString(LLStdStringHandle canonical_name, std::string& value) +bool LLXmlTreeNode::getFastAttributeString(LLStdStringHandle canonical_name, std::string& value) { const std::string *s = getAttribute( canonical_name ); if( !s ) { - return FALSE; + return false; } value = *s; - return TRUE; + return true; } @@ -316,97 +316,97 @@ bool LLXmlTreeNode::getAttributeBOOL(const std::string& name, bool& value) return getFastAttributeBOOL(canonical_name, value); } -BOOL LLXmlTreeNode::getAttributeU8(const std::string& name, U8& value) +bool LLXmlTreeNode::getAttributeU8(const std::string& name, U8& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeU8(canonical_name, value); } -BOOL LLXmlTreeNode::getAttributeS8(const std::string& name, S8& value) +bool LLXmlTreeNode::getAttributeS8(const std::string& name, S8& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeS8(canonical_name, value); } -BOOL LLXmlTreeNode::getAttributeS16(const std::string& name, S16& value) +bool LLXmlTreeNode::getAttributeS16(const std::string& name, S16& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeS16(canonical_name, value); } -BOOL LLXmlTreeNode::getAttributeU16(const std::string& name, U16& value) +bool LLXmlTreeNode::getAttributeU16(const std::string& name, U16& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeU16(canonical_name, value); } -BOOL LLXmlTreeNode::getAttributeU32(const std::string& name, U32& value) +bool LLXmlTreeNode::getAttributeU32(const std::string& name, U32& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeU32(canonical_name, value); } -BOOL LLXmlTreeNode::getAttributeS32(const std::string& name, S32& value) +bool LLXmlTreeNode::getAttributeS32(const std::string& name, S32& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeS32(canonical_name, value); } -BOOL LLXmlTreeNode::getAttributeF32(const std::string& name, F32& value) +bool LLXmlTreeNode::getAttributeF32(const std::string& name, F32& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeF32(canonical_name, value); } -BOOL LLXmlTreeNode::getAttributeF64(const std::string& name, F64& value) +bool LLXmlTreeNode::getAttributeF64(const std::string& name, F64& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeF64(canonical_name, value); } -BOOL LLXmlTreeNode::getAttributeColor(const std::string& name, LLColor4& value) +bool LLXmlTreeNode::getAttributeColor(const std::string& name, LLColor4& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeColor(canonical_name, value); } -BOOL LLXmlTreeNode::getAttributeColor4(const std::string& name, LLColor4& value) +bool LLXmlTreeNode::getAttributeColor4(const std::string& name, LLColor4& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeColor4(canonical_name, value); } -BOOL LLXmlTreeNode::getAttributeColor4U(const std::string& name, LLColor4U& value) +bool LLXmlTreeNode::getAttributeColor4U(const std::string& name, LLColor4U& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeColor4U(canonical_name, value); } -BOOL LLXmlTreeNode::getAttributeVector3(const std::string& name, LLVector3& value) +bool LLXmlTreeNode::getAttributeVector3(const std::string& name, LLVector3& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeVector3(canonical_name, value); } -BOOL LLXmlTreeNode::getAttributeVector3d(const std::string& name, LLVector3d& value) +bool LLXmlTreeNode::getAttributeVector3d(const std::string& name, LLVector3d& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeVector3d(canonical_name, value); } -BOOL LLXmlTreeNode::getAttributeQuat(const std::string& name, LLQuaternion& value) +bool LLXmlTreeNode::getAttributeQuat(const std::string& name, LLQuaternion& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeQuat(canonical_name, value); } -BOOL LLXmlTreeNode::getAttributeUUID(const std::string& name, LLUUID& value) +bool LLXmlTreeNode::getAttributeUUID(const std::string& name, LLUUID& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeUUID(canonical_name, value); } -BOOL LLXmlTreeNode::getAttributeString(const std::string& name, std::string& value) +bool LLXmlTreeNode::getAttributeString(const std::string& name, std::string& value) { LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); return getFastAttributeString(canonical_name, value); @@ -506,8 +506,8 @@ LLXmlTreeParser::LLXmlTreeParser(LLXmlTree* tree) : mTree(tree), mRoot( NULL ), mCurrent( NULL ), - mDump( FALSE ), - mKeepContents(FALSE) + mDump( false ), + mKeepContents(false) { } @@ -515,14 +515,14 @@ LLXmlTreeParser::~LLXmlTreeParser() { } -BOOL LLXmlTreeParser::parseFile(const std::string &path, LLXmlTreeNode** root, BOOL keep_contents) +bool LLXmlTreeParser::parseFile(const std::string &path, LLXmlTreeNode** root, bool keep_contents) { llassert( !mRoot ); llassert( !mCurrent ); mKeepContents = keep_contents; - BOOL success = LLXmlParser::parseFile(path); + bool success = LLXmlParser::parseFile(path); *root = mRoot; mRoot = NULL; @@ -685,7 +685,7 @@ void LLXmlTreeParser::unparsedEntityDecl( void test_llxmltree() { LLXmlTree tree; - BOOL success = tree.parseFile( "test.xml" ); + bool success = tree.parseFile( "test.xml" ); if( success ) { tree.dump(); diff --git a/indra/llxml/llxmltree.h b/indra/llxml/llxmltree.h index 5d33e2c660..5d15c4c7f5 100644 --- a/indra/llxml/llxmltree.h +++ b/indra/llxml/llxmltree.h @@ -55,7 +55,7 @@ public: virtual ~LLXmlTree(); void cleanup(); - virtual BOOL parseFile(const std::string &path, BOOL keep_contents = TRUE); + virtual bool parseFile(const std::string &path, bool keep_contents = true); LLXmlTreeNode* getRoot() { return mRoot; } @@ -97,50 +97,50 @@ public: { return mName; } - BOOL hasName( const std::string& name ) + bool hasName( const std::string& name ) { return mName == name; } - BOOL hasAttribute( const std::string& name ); + bool hasAttribute( const std::string& name ); // Fast versions use cannonical_name handlee to entru in LLXmlTree::sAttributeKeys string table bool getFastAttributeBOOL( LLStdStringHandle cannonical_name, bool& value ); - BOOL getFastAttributeU8( LLStdStringHandle cannonical_name, U8& value ); - BOOL getFastAttributeS8( LLStdStringHandle cannonical_name, S8& value ); - BOOL getFastAttributeU16( LLStdStringHandle cannonical_name, U16& value ); - BOOL getFastAttributeS16( LLStdStringHandle cannonical_name, S16& value ); - BOOL getFastAttributeU32( LLStdStringHandle cannonical_name, U32& value ); - BOOL getFastAttributeS32( LLStdStringHandle cannonical_name, S32& value ); - BOOL getFastAttributeF32( LLStdStringHandle cannonical_name, F32& value ); - BOOL getFastAttributeF64( LLStdStringHandle cannonical_name, F64& value ); - BOOL getFastAttributeColor( LLStdStringHandle cannonical_name, LLColor4& value ); - BOOL getFastAttributeColor4( LLStdStringHandle cannonical_name, LLColor4& value ); - BOOL getFastAttributeColor4U( LLStdStringHandle cannonical_name, LLColor4U& value ); - BOOL getFastAttributeVector3( LLStdStringHandle cannonical_name, LLVector3& value ); - BOOL getFastAttributeVector3d( LLStdStringHandle cannonical_name, LLVector3d& value ); - BOOL getFastAttributeQuat( LLStdStringHandle cannonical_name, LLQuaternion& value ); - BOOL getFastAttributeUUID( LLStdStringHandle cannonical_name, LLUUID& value ); - BOOL getFastAttributeString( LLStdStringHandle cannonical_name, std::string& value ); + bool getFastAttributeU8( LLStdStringHandle cannonical_name, U8& value ); + bool getFastAttributeS8( LLStdStringHandle cannonical_name, S8& value ); + bool getFastAttributeU16( LLStdStringHandle cannonical_name, U16& value ); + bool getFastAttributeS16( LLStdStringHandle cannonical_name, S16& value ); + bool getFastAttributeU32( LLStdStringHandle cannonical_name, U32& value ); + bool getFastAttributeS32( LLStdStringHandle cannonical_name, S32& value ); + bool getFastAttributeF32( LLStdStringHandle cannonical_name, F32& value ); + bool getFastAttributeF64( LLStdStringHandle cannonical_name, F64& value ); + bool getFastAttributeColor( LLStdStringHandle cannonical_name, LLColor4& value ); + bool getFastAttributeColor4( LLStdStringHandle cannonical_name, LLColor4& value ); + bool getFastAttributeColor4U( LLStdStringHandle cannonical_name, LLColor4U& value ); + bool getFastAttributeVector3( LLStdStringHandle cannonical_name, LLVector3& value ); + bool getFastAttributeVector3d( LLStdStringHandle cannonical_name, LLVector3d& value ); + bool getFastAttributeQuat( LLStdStringHandle cannonical_name, LLQuaternion& value ); + bool getFastAttributeUUID( LLStdStringHandle cannonical_name, LLUUID& value ); + bool getFastAttributeString( LLStdStringHandle cannonical_name, std::string& value ); // Normal versions find 'name' in LLXmlTree::sAttributeKeys then call fast versions virtual bool getAttributeBOOL( const std::string& name, bool& value ); - virtual BOOL getAttributeU8( const std::string& name, U8& value ); - virtual BOOL getAttributeS8( const std::string& name, S8& value ); - virtual BOOL getAttributeU16( const std::string& name, U16& value ); - virtual BOOL getAttributeS16( const std::string& name, S16& value ); - virtual BOOL getAttributeU32( const std::string& name, U32& value ); - virtual BOOL getAttributeS32( const std::string& name, S32& value ); - virtual BOOL getAttributeF32( const std::string& name, F32& value ); - virtual BOOL getAttributeF64( const std::string& name, F64& value ); - virtual BOOL getAttributeColor( const std::string& name, LLColor4& value ); - virtual BOOL getAttributeColor4( const std::string& name, LLColor4& value ); - virtual BOOL getAttributeColor4U( const std::string& name, LLColor4U& value ); - virtual BOOL getAttributeVector3( const std::string& name, LLVector3& value ); - virtual BOOL getAttributeVector3d( const std::string& name, LLVector3d& value ); - virtual BOOL getAttributeQuat( const std::string& name, LLQuaternion& value ); - virtual BOOL getAttributeUUID( const std::string& name, LLUUID& value ); - virtual BOOL getAttributeString( const std::string& name, std::string& value ); + virtual bool getAttributeU8( const std::string& name, U8& value ); + virtual bool getAttributeS8( const std::string& name, S8& value ); + virtual bool getAttributeU16( const std::string& name, U16& value ); + virtual bool getAttributeS16( const std::string& name, S16& value ); + virtual bool getAttributeU32( const std::string& name, U32& value ); + virtual bool getAttributeS32( const std::string& name, S32& value ); + virtual bool getAttributeF32( const std::string& name, F32& value ); + virtual bool getAttributeF64( const std::string& name, F64& value ); + virtual bool getAttributeColor( const std::string& name, LLColor4& value ); + virtual bool getAttributeColor4( const std::string& name, LLColor4& value ); + virtual bool getAttributeColor4U( const std::string& name, LLColor4U& value ); + virtual bool getAttributeVector3( const std::string& name, LLVector3& value ); + virtual bool getAttributeVector3d( const std::string& name, LLVector3d& value ); + virtual bool getAttributeQuat( const std::string& name, LLQuaternion& value ); + virtual bool getAttributeUUID( const std::string& name, LLUUID& value ); + virtual bool getAttributeString( const std::string& name, std::string& value ); const std::string& getContents() { @@ -199,7 +199,7 @@ public: LLXmlTreeParser(LLXmlTree* tree); virtual ~LLXmlTreeParser(); - BOOL parseFile(const std::string &path, LLXmlTreeNode** root, BOOL keep_contents ); + bool parseFile(const std::string &path, LLXmlTreeNode** root, bool keep_contents ); protected: const std::string& tabs(); @@ -227,8 +227,8 @@ protected: LLXmlTree* mTree; LLXmlTreeNode* mRoot; LLXmlTreeNode* mCurrent; - BOOL mDump; // Dump parse tree to LL_INFOS() as it is read. - BOOL mKeepContents; + bool mDump; // Dump parse tree to LL_INFOS() as it is read. + bool mKeepContents; }; #endif // LL_LLXMLTREE_H -- cgit v1.2.3 From 8c16ec2b53153a10f40181e0e8108d24331451d4 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Tue, 20 Feb 2024 13:57:07 +0100 Subject: Convert BOOL to bool in LLControlGroup and related classes --- indra/llxml/llcontrol.cpp | 30 ++++++++++-------------------- indra/llxml/llcontrol.h | 14 ++++++-------- indra/llxml/llxmlnode.h | 2 +- 3 files changed, 17 insertions(+), 29 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index 2c04147a5a..e215ff57fb 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -59,8 +59,6 @@ template <> eControlType get_control_type(); template <> eControlType get_control_type(); template <> eControlType get_control_type(); template <> eControlType get_control_type(); -// Yay BOOL, its really an S32. -//template <> eControlType get_control_type () ; template <> eControlType get_control_type(); template <> eControlType get_control_type(); @@ -465,7 +463,7 @@ std::string LLControlGroup::typeEnumToString(eControlType typeenum) return mTypeString[typeenum]; } -LLControlVariable* LLControlGroup::declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, BOOL hidefromsettingseditor) +LLControlVariable* LLControlGroup::declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, bool hidefromsettingseditor) { LLControlVariable* existing_control = getControl(name); if (existing_control) @@ -562,9 +560,9 @@ void LLControlGroup::incrCount(const std::string& name) getCount[name] = getCount[name].asInteger() + 1; } -BOOL LLControlGroup::getBOOL(const std::string& name) +bool LLControlGroup::getBOOL(const std::string& name) { - return (BOOL)get(name); + return get(name); } S32 LLControlGroup::getS32(const std::string& name) @@ -659,7 +657,7 @@ LLSD LLControlGroup::asLLSD(bool diffs_only) return result; } -BOOL LLControlGroup::controlExists(const std::string& name) +bool LLControlGroup::controlExists(const std::string& name) { ctrl_name_table_t::iterator iter = mNameTable.find(name); return iter != mNameTable.end(); @@ -670,7 +668,7 @@ BOOL LLControlGroup::controlExists(const std::string& name) // Set functions //------------------------------------------------------------------- -void LLControlGroup::setBOOL(const std::string& name, BOOL val) +void LLControlGroup::setBOOL(const std::string& name, bool val) { set(name, val); } @@ -755,7 +753,7 @@ void LLControlGroup::setUntypedValue(const std::string& name, const LLSD& val) //--------------------------------------------------------------- // Returns number of controls loaded, so 0 if failure -U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require_declaration, eControlType declare_as) +U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, bool require_declaration, eControlType declare_as) { std::string name; @@ -791,7 +789,7 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require { name = child_nodep->getName(); - BOOL declared = controlExists(name); + bool declared = controlExists(name); if (require_declaration && !declared) { @@ -952,7 +950,7 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require return validitems; } -U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only) +U32 LLControlGroup::saveToFile(const std::string& filename, bool nondefault_only) { LLSD settings; int num_saved = 0; @@ -1162,7 +1160,7 @@ void main() bar = new LLControlVariable("gBar", 10, 2, 22); gGlobals.addEntry("gBar", bar); - baz = new LLControlVariable("gBaz", FALSE); + baz = new LLControlVariable("gBaz", false); gGlobals.addEntry("gBaz", baz); // test retrieval @@ -1224,13 +1222,7 @@ template <> eControlType get_control_type () { return TYPE_BOOLEAN; } -/* -// Yay BOOL, its really an S32. -template <> eControlType get_control_type () -{ - return TYPE_BOOLEAN; -} -*/ + template <> eControlType get_control_type() { return TYPE_STRING; @@ -1485,7 +1477,6 @@ DECL_LLCC(U32, (U32)666); DECL_LLCC(S32, (S32)-666); DECL_LLCC(F32, (F32)-666.666); DECL_LLCC(bool, true); -DECL_LLCC(BOOL, FALSE); static LLCachedControl mySetting_string("TestCachedControlstring", "Default String Value"); DECL_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f)); DECL_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f)); @@ -1506,7 +1497,6 @@ void test_cached_control() TEST_LLCC(S32, (S32)-666); TEST_LLCC(F32, (F32)-666.666); TEST_LLCC(bool, true); - TEST_LLCC(BOOL, FALSE); if((std::string)mySetting_string != "Default String Value") LL_ERRS() << "Fail string" << LL_ENDL; TEST_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f)); TEST_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f)); diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index d682b2c7c7..2289dc8841 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -210,7 +210,7 @@ public: }; void applyToAll(ApplyFunctor* func); - LLControlVariable* declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, BOOL hidefromsettingseditor = FALSE); + LLControlVariable* declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, bool hidefromsettingseditor = false); LLControlVariable* declareU32(const std::string& name, U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); LLControlVariable* declareS32(const std::string& name, S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); LLControlVariable* declareF32(const std::string& name, F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); @@ -226,7 +226,7 @@ public: std::string getString(const std::string& name); std::string getText(const std::string& name); - BOOL getBOOL(const std::string& name); + bool getBOOL(const std::string& name); S32 getS32(const std::string& name); F32 getF32(const std::string& name); U32 getU32(const std::string& name); @@ -265,7 +265,7 @@ public: return convert_from_llsd(value, type, name); } - void setBOOL(const std::string& name, BOOL val); + void setBOOL(const std::string& name, bool val); void setS32(const std::string& name, S32 val); void setF32(const std::string& name, F32 val); void setU32(const std::string& name, U32 val); @@ -295,13 +295,13 @@ public: } } - BOOL controlExists(const std::string& name); + bool controlExists(const std::string& name); // 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, BOOL require_declaration = TRUE, eControlType declare_as = TYPE_STRING); - U32 saveToFile(const std::string& filename, BOOL nondefault_only); + 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(); void incrCount(const std::string& name); @@ -435,8 +435,6 @@ template <> eControlType get_control_type(); template <> eControlType get_control_type(); template <> eControlType get_control_type(); template <> eControlType get_control_type(); -// Yay BOOL, its really an S32. -//template <> eControlType get_control_type () template <> eControlType get_control_type(); template <> eControlType get_control_type(); template <> eControlType get_control_type(); diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index 21a7dee4cc..d5b8b36d86 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -296,7 +296,7 @@ public: XML_Parser *mParser; // Temporary pointer while loading - BOOL mIsAttribute; // Flag is only used for output formatting + bool mIsAttribute; // Flag is only used for output formatting U32 mVersionMajor; // Version of this tag to use U32 mVersionMinor; U32 mLength; // If the length is nonzero, then only return arrays of this length -- cgit v1.2.3 From 3ffe63b8a4e8a3ceda3f6d204e4b5bb0c80d0870 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 21 Feb 2024 16:49:48 +0100 Subject: Convert remaining BOOLs in llxml and introduce std::string_view --- indra/llxml/llcontrol.cpp | 124 +++++++++++++++++++++++----------------------- indra/llxml/llcontrol.h | 92 +++++++++++++++++----------------- 2 files changed, 108 insertions(+), 108 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index e215ff57fb..f665621b66 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -77,19 +77,19 @@ template <> LLSD convert_to_llsd(const LLColor4& in); template <> LLSD convert_to_llsd(const LLColor3& in); template <> LLSD convert_to_llsd(const LLColor4U& in); -template <> bool convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template <> S32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template <> U32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template <> F32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template <> std::string convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template <> LLWString convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template <> LLVector3 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template <> LLVector3d convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template <> LLRect convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template <> LLColor4 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template <> LLColor4U convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template <> LLColor3 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template <> LLSD convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); +template <> bool convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> S32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> U32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> F32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> std::string convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> LLWString convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> LLVector3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> LLVector3d convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> LLRect convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> LLColor4 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> LLColor4U convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> LLColor3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> LLSD convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); //this defines the current version of the settings file const S32 CURRENT_VERSION = 101; @@ -218,12 +218,12 @@ void LLControlVariable::setValue(const LLSD& new_value, bool saved_value) LLSD storable_value = getComparableValue(new_value); LLSD original_value = getValue(); - bool value_changed = llsd_compare(original_value, storable_value) == FALSE; + bool value_changed = llsd_compare(original_value, storable_value) == false; if(saved_value) { // If we're going to save this value, return to default but don't fire resetToDefault(false); - if (llsd_compare(mValues.back(), storable_value) == FALSE) + if (llsd_compare(mValues.back(), storable_value) == false) { mValues.push_back(storable_value); } @@ -233,7 +233,7 @@ void LLControlVariable::setValue(const LLSD& new_value, bool saved_value) // This is an unsaved value. Its needs to reside at // mValues[2] (or greater). It must not affect // the result of getSaveValue() - if (llsd_compare(mValues.back(), storable_value) == FALSE) + if (llsd_compare(mValues.back(), storable_value) == false) { while(mValues.size() > 2) { @@ -267,7 +267,7 @@ void LLControlVariable::setDefaultValue(const LLSD& value) LLSD comparable_value = getComparableValue(value); LLSD original_value = getValue(); - bool value_changed = (llsd_compare(original_value, comparable_value) == FALSE); + bool value_changed = (llsd_compare(original_value, comparable_value) == false); resetToDefault(false); mValues[0] = comparable_value; if(value_changed) @@ -341,14 +341,14 @@ LLSD LLControlVariable::getSaveValue() const return mValues[0]; } -LLPointer LLControlGroup::getControl(const std::string& name) +LLPointer LLControlGroup::getControl(std::string_view name) { if (mSettingsProfile) { incrCount(name); } - ctrl_name_table_t::iterator iter = mNameTable.find(name); + ctrl_name_table_t::iterator iter = mNameTable.find(name.data()); return iter == mNameTable.end() ? LLPointer() : iter->second; } @@ -551,46 +551,46 @@ LLControlVariable* LLControlGroup::declareLLSD(const std::string& name, const LL return declareControl(name, TYPE_LLSD, initial_val, comment, persist); } -void LLControlGroup::incrCount(const std::string& name) +void LLControlGroup::incrCount(std::string_view name) { if (0.0 == start_time) { start_time = LLTimer::getTotalSeconds(); } - getCount[name] = getCount[name].asInteger() + 1; + getCount[name.data()] = getCount[name.data()].asInteger() + 1; } -bool LLControlGroup::getBOOL(const std::string& name) +bool LLControlGroup::getBOOL(std::string_view name) { return get(name); } -S32 LLControlGroup::getS32(const std::string& name) +S32 LLControlGroup::getS32(std::string_view name) { return get(name); } -U32 LLControlGroup::getU32(const std::string& name) +U32 LLControlGroup::getU32(std::string_view name) { return get(name); } -F32 LLControlGroup::getF32(const std::string& name) +F32 LLControlGroup::getF32(std::string_view name) { return get(name); } -std::string LLControlGroup::getString(const std::string& name) +std::string LLControlGroup::getString(std::string_view name) { return get(name); } -LLWString LLControlGroup::getWString(const std::string& name) +LLWString LLControlGroup::getWString(std::string_view name) { return get(name); } -std::string LLControlGroup::getText(const std::string& name) +std::string LLControlGroup::getText(std::string_view name) { std::string utf8_string = getString(name); LLStringUtil::replaceChar(utf8_string, '^', '\n'); @@ -598,43 +598,43 @@ std::string LLControlGroup::getText(const std::string& name) return (utf8_string); } -LLVector3 LLControlGroup::getVector3(const std::string& name) +LLVector3 LLControlGroup::getVector3(std::string_view name) { return get(name); } -LLVector3d LLControlGroup::getVector3d(const std::string& name) +LLVector3d LLControlGroup::getVector3d(std::string_view name) { return get(name); } -LLQuaternion LLControlGroup::getQuaternion(const std::string& name) +LLQuaternion LLControlGroup::getQuaternion(std::string_view name) { return get(name); } -LLRect LLControlGroup::getRect(const std::string& name) +LLRect LLControlGroup::getRect(std::string_view name) { return get(name); } -LLColor4 LLControlGroup::getColor(const std::string& name) +LLColor4 LLControlGroup::getColor(std::string_view name) { return get(name); } -LLColor4 LLControlGroup::getColor4(const std::string& name) +LLColor4 LLControlGroup::getColor4(std::string_view name) { return get(name); } -LLColor3 LLControlGroup::getColor3(const std::string& name) +LLColor3 LLControlGroup::getColor3(std::string_view name) { return get(name); } -LLSD LLControlGroup::getLLSD(const std::string& name) +LLSD LLControlGroup::getLLSD(std::string_view name) { return get(name); } @@ -668,67 +668,67 @@ bool LLControlGroup::controlExists(const std::string& name) // Set functions //------------------------------------------------------------------- -void LLControlGroup::setBOOL(const std::string& name, bool val) +void LLControlGroup::setBOOL(std::string_view name, bool val) { set(name, val); } -void LLControlGroup::setS32(const std::string& name, S32 val) +void LLControlGroup::setS32(std::string_view name, S32 val) { set(name, val); } -void LLControlGroup::setF32(const std::string& name, F32 val) +void LLControlGroup::setF32(std::string_view name, F32 val) { set(name, val); } -void LLControlGroup::setU32(const std::string& name, U32 val) +void LLControlGroup::setU32(std::string_view name, U32 val) { set(name, val); } -void LLControlGroup::setString(const std::string& name, const std::string &val) +void LLControlGroup::setString(std::string_view name, const std::string &val) { set(name, val); } -void LLControlGroup::setVector3(const std::string& name, const LLVector3 &val) +void LLControlGroup::setVector3(std::string_view name, const LLVector3 &val) { set(name, val); } -void LLControlGroup::setVector3d(const std::string& name, const LLVector3d &val) +void LLControlGroup::setVector3d(std::string_view name, const LLVector3d &val) { set(name, val); } -void LLControlGroup::setQuaternion(const std::string& name, const LLQuaternion &val) +void LLControlGroup::setQuaternion(std::string_view name, const LLQuaternion &val) { set(name, val); } -void LLControlGroup::setRect(const std::string& name, const LLRect &val) +void LLControlGroup::setRect(std::string_view name, const LLRect &val) { set(name, val); } -void LLControlGroup::setColor4(const std::string& name, const LLColor4 &val) +void LLControlGroup::setColor4(std::string_view name, const LLColor4 &val) { set(name, val); } -void LLControlGroup::setLLSD(const std::string& name, const LLSD& val) +void LLControlGroup::setLLSD(std::string_view name, const LLSD& val) { set(name, val); } -void LLControlGroup::setUntypedValue(const std::string& name, const LLSD& val) +void LLControlGroup::setUntypedValue(std::string_view name, const LLSD& val) { if (name.empty()) { @@ -1305,19 +1305,19 @@ template <> LLSD convert_to_llsd(const LLColor4U& in) template<> -bool convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) +bool convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) { if (type == TYPE_BOOLEAN) return sd.asBoolean(); else { CONTROL_ERRS << "Invalid BOOL value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return FALSE; + return false; } } template<> -S32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) +S32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) { if (type == TYPE_S32) return sd.asInteger(); @@ -1329,7 +1329,7 @@ S32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& } template<> -U32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) +U32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) { if (type == TYPE_U32) return sd.asInteger(); @@ -1341,7 +1341,7 @@ U32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& } template<> -F32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) +F32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) { if (type == TYPE_F32) return (F32) sd.asReal(); @@ -1353,7 +1353,7 @@ F32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& } template<> -std::string convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) +std::string convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) { if (type == TYPE_STRING) return sd.asString(); @@ -1365,13 +1365,13 @@ std::string convert_from_llsd(const LLSD& sd, eControlType type, co } template<> -LLWString convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) +LLWString convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) { return utf8str_to_wstring(convert_from_llsd(sd, type, control_name)); } template<> -LLVector3 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) +LLVector3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) { if (type == TYPE_VEC3) return (LLVector3)sd; @@ -1383,7 +1383,7 @@ LLVector3 convert_from_llsd(const LLSD& sd, eControlType type, const } template<> -LLVector3d convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) +LLVector3d convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) { if (type == TYPE_VEC3D) return (LLVector3d)sd; @@ -1395,7 +1395,7 @@ LLVector3d convert_from_llsd(const LLSD& sd, eControlType type, cons } template<> -LLQuaternion convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) +LLQuaternion convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) { if (type == TYPE_QUAT) return (LLQuaternion)sd; @@ -1407,7 +1407,7 @@ LLQuaternion convert_from_llsd(const LLSD& sd, eControlType type, } template<> -LLRect convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) +LLRect convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) { if (type == TYPE_RECT) return LLRect(sd); @@ -1420,7 +1420,7 @@ LLRect convert_from_llsd(const LLSD& sd, eControlType type, const std::s template<> -LLColor4 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) +LLColor4 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) { if (type == TYPE_COL4) { @@ -1452,7 +1452,7 @@ LLColor4 convert_from_llsd(const LLSD& sd, eControlType type, const st } template<> -LLColor3 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) +LLColor3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) { if (type == TYPE_COL3) return sd; @@ -1464,7 +1464,7 @@ LLColor3 convert_from_llsd(const LLSD& sd, eControlType type, const st } template<> -LLSD convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) +LLSD convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) { return sd; } diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 2289dc8841..a8bc584c48 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -144,7 +144,7 @@ public: LLSD getSaveValue() const; void set(const LLSD& val) { setValue(val); } - void setValue(const LLSD& value, bool saved_value = TRUE); + void setValue(const LLSD& value, bool saved_value = true); void setDefaultValue(const LLSD& value); void setPersist(ePersist); void setHiddenFromSettingsEditor(bool hide); @@ -177,7 +177,7 @@ LLSD convert_to_llsd(const T& in) } template -T convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) +T convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) { // needs specialization return T(sd); @@ -201,7 +201,7 @@ public: ~LLControlGroup(); void cleanup(); - LLControlVariablePtr getControl(const std::string& name); + LLControlVariablePtr getControl(std::string_view name); struct ApplyFunctor { @@ -224,28 +224,28 @@ public: LLControlVariable* declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); LLControlVariable* declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - std::string getString(const std::string& name); - std::string getText(const std::string& name); - bool getBOOL(const std::string& name); - S32 getS32(const std::string& name); - F32 getF32(const std::string& name); - U32 getU32(const std::string& name); + std::string getString(std::string_view name); + std::string getText(std::string_view name); + bool getBOOL(std::string_view name); + S32 getS32(std::string_view name); + F32 getF32(std::string_view name); + U32 getU32(std::string_view name); - LLWString getWString(const std::string& name); - LLVector3 getVector3(const std::string& name); - LLVector3d getVector3d(const std::string& name); - LLRect getRect(const std::string& name); - LLSD getLLSD(const std::string& name); - LLQuaternion getQuaternion(const std::string& name); + LLWString getWString(std::string_view name); + LLVector3 getVector3(std::string_view name); + LLVector3d getVector3d(std::string_view name); + LLRect getRect(std::string_view name); + LLSD getLLSD(std::string_view name); + LLQuaternion getQuaternion(std::string_view name); - LLColor4 getColor(const std::string& name); - LLColor4 getColor4(const std::string& name); - LLColor3 getColor3(const std::string& name); + LLColor4 getColor(std::string_view name); + LLColor4 getColor4(std::string_view name); + LLColor3 getColor3(std::string_view name); LLSD asLLSD(bool diffs_only); // generic getter - template T get(const std::string& name) + template T get(std::string_view name) { LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; LLControlVariable* control = getControl(name); @@ -265,23 +265,23 @@ public: return convert_from_llsd(value, type, name); } - void setBOOL(const std::string& name, bool val); - void setS32(const std::string& name, S32 val); - void setF32(const std::string& name, F32 val); - void setU32(const std::string& name, U32 val); - void setString(const std::string& name, const std::string& val); - void setVector3(const std::string& name, const LLVector3 &val); - void setVector3d(const std::string& name, const LLVector3d &val); - void setQuaternion(const std::string& name, const LLQuaternion &val); - void setRect(const std::string& name, const LLRect &val); - void setColor4(const std::string& name, const LLColor4 &val); - void setLLSD(const std::string& name, const LLSD& val); + void setBOOL(std::string_view name, bool val); + void setS32(std::string_view name, S32 val); + void setF32(std::string_view name, F32 val); + void setU32(std::string_view name, U32 val); + void setString(std::string_view name, const std::string& val); + void setVector3(std::string_view name, const LLVector3 &val); + void setVector3d(std::string_view name, const LLVector3d &val); + void setQuaternion(std::string_view name, const LLQuaternion &val); + void setRect(std::string_view name, const LLRect &val); + void setColor4(std::string_view name, const LLColor4 &val); + void setLLSD(std::string_view name, const LLSD& val); // type agnostic setter that takes LLSD - void setUntypedValue(const std::string& name, const LLSD& val); + void setUntypedValue(std::string_view name, const LLSD& val); // generic setter - template void set(const std::string& name, const T& val) + template void set(std::string_view name, const T& val) { LLControlVariable* control = getControl(name); @@ -304,7 +304,7 @@ public: 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(); - void incrCount(const std::string& name); + void incrCount(std::string_view name); bool mSettingsProfile; }; @@ -452,19 +452,19 @@ template <> LLSD convert_to_llsd(const LLRect& in); template <> LLSD convert_to_llsd(const LLColor4& in); template <> LLSD convert_to_llsd(const LLColor3& in); -template<> std::string convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template<> LLWString convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template<> LLVector3 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template<> LLVector3d convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template<> LLQuaternion convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template<> LLRect convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template<> bool convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template<> S32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template<> F32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template<> U32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template<> LLColor3 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template<> LLColor4 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); -template<> LLSD convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name); +template<> std::string convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> LLWString convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> LLVector3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> LLVector3d convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> LLQuaternion convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> LLRect convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> bool convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> S32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> F32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> U32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> LLColor3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> LLColor4 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> LLSD convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); //#define TEST_CACHED_CONTROL 1 #ifdef TEST_CACHED_CONTROL -- cgit v1.2.3 From e160758b5c32f7b4b9622a5c25c7c53070395c7d Mon Sep 17 00:00:00 2001 From: Ansariel Date: Fri, 1 Mar 2024 13:48:46 +0100 Subject: Convert remaining TRUE/FALSE to true/false --- indra/llxml/llcontrol.cpp | 4 ++-- indra/llxml/tests/llcontrol_test.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index f665621b66..e626bac7d0 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -1002,7 +1002,7 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v { infile.close(); LL_WARNS("Settings") << "Unable to parse LLSD control file " << filename << ". Trying Legacy Method." << LL_ENDL; - return loadFromFileLegacy(filename, TRUE, TYPE_STRING); + return loadFromFileLegacy(filename, true, TYPE_STRING); } U32 validitems = 0; @@ -1188,7 +1188,7 @@ void main() // ...invalid data type getfoo = (F32_CONTROL) gGlobals.resolveName("gFoo"); - getfoo->set(TRUE); + getfoo->set(true); getfoo->dump(); // ...out of range data diff --git a/indra/llxml/tests/llcontrol_test.cpp b/indra/llxml/tests/llcontrol_test.cpp index f7e43d6def..0c0ef61d23 100644 --- a/indra/llxml/tests/llcontrol_test.cpp +++ b/indra/llxml/tests/llcontrol_test.cpp @@ -112,7 +112,7 @@ namespace tut LLControlGroup test_cg("foo2"); std::string temp_test_file = (mTestConfigDir + "setting_llsd_temp.xml"); mCleanups.push_back(temp_test_file); - mCG->saveToFile(temp_test_file.c_str(), TRUE); + mCG->saveToFile(temp_test_file.c_str(), true); results = test_cg.loadFromFile(temp_test_file.c_str()); ensure("number of changed settings loaded", (results == 1)); ensure("value of changed settings loaded", (test_cg.getU32("TestSetting") == 13)); @@ -129,12 +129,12 @@ namespace tut int results = mCG->loadFromFile(mTestConfigFile.c_str(), true); LLControlVariable* control = mCG->getControl("TestSetting"); LLSD new_value = 13; - control->setValue(new_value, FALSE); + control->setValue(new_value, false); ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13); LLControlGroup test_cg("foo3"); std::string temp_test_file = (mTestConfigDir + "setting_llsd_persist_temp.xml"); mCleanups.push_back(temp_test_file); - mCG->saveToFile(temp_test_file.c_str(), TRUE); + mCG->saveToFile(temp_test_file.c_str(), true); results = test_cg.loadFromFile(temp_test_file.c_str()); //If we haven't changed any settings, then we shouldn't have any settings to load ensure("number of non-persisted changed settings loaded", (results == 0)); -- cgit v1.2.3 From a865d423974ea06dffa47798c81e98e7570b02ec Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Tue, 5 Mar 2024 17:03:11 +0100 Subject: viewer#819 Avoid reading the same XML file multiple times --- indra/llxml/llcontrol.cpp | 24 +++++++-------- indra/llxml/llcontrol.h | 2 +- indra/llxml/llxmlnode.cpp | 78 +++++++++++++++++++++++++++++++---------------- indra/llxml/llxmlnode.h | 26 ++++++++-------- indra/llxml/llxmltree.cpp | 45 +++++++++++++++++++++++++-- indra/llxml/llxmltree.h | 4 ++- 6 files changed, 122 insertions(+), 57 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index e626bac7d0..71ba2b88bc 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, bool require_declaration, eControlType declare_as) +U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, const std::string& xml, bool require_declaration, eControlType declare_as) { std::string name; LLXmlTree xml_controls; - if (!xml_controls.parseFile(filename)) + if (!xml_controls.parseString(xml)) { LL_WARNS("Settings") << "Unable to open control file " << filename << LL_ENDL; return 0; @@ -772,7 +772,7 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, bool require 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; - llifstream infile; - infile.open(filename.c_str()); - if(!infile.is_open()) + + std::string xml = gDirUtilp->getFileContents(filename); + if (xml.empty()) { LL_WARNS("Settings") << "Cannot find file " << filename << " to load." << LL_ENDL; return 0; } - if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(settings, infile)) + std::stringstream stream(xml); + if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(settings, stream)) { - infile.close(); LL_WARNS("Settings") << "Unable to parse LLSD control file " << filename << ". Trying Legacy Method." << LL_ENDL; - return loadFromFileLegacy(filename, true, TYPE_STRING); + return loadFromFileLegacy(filename, xml, 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 a8bc584c48..e148b74292 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, bool require_declaration = true, eControlType declare_as = TYPE_STRING); + U32 loadFromFileLegacy(const std::string& filename, const std::string& xml, 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 9c7ac66f01..627e99a1e6 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -650,34 +650,56 @@ bool LLXMLNode::updateNode( return true; } -// static -bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXMLNode* defaults_tree) +static std::map sXMLCache; +static LLSharedMutex sXMLCacheMutex; + +static void saveToCache(const std::string& filename, LLXMLNodePtr& node) { - // 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); + LLExclusiveMutexLock lock(&sXMLCacheMutex); + sXMLCache.emplace(filename, node.notNull() ? node->deepCopy() : nullptr); +} - U8* buffer = new U8[length+1]; - size_t nread = fread(buffer, 1, length, fp); - buffer[nread] = 0; - fclose(fp); +static bool loadFromCache(const std::string& filename, LLXMLNodePtr& node) +{ + LLSharedMutexLock lock(&sXMLCacheMutex); + auto it = sXMLCache.find(filename); + if (it == sXMLCache.end()) + return false; + node = it->second.notNull() ? it->second->deepCopy() : nullptr; + return node.notNull(); +} - bool rv = parseBuffer(buffer, nread, node, defaults_tree); - delete [] buffer; - return rv; +// 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)) + 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, defaults_tree)) + { + if (cacheable) + { + saveToCache(filename, node); + } + return true; + } + + node = nullptr; + return false; } // static bool LLXMLNode::parseBuffer( - U8* buffer, + const char* buffer, U32 length, LLXMLNodePtr& node, LLXMLNode* defaults) @@ -696,7 +718,7 @@ bool LLXMLNode::parseBuffer( XML_SetUserData(my_parser, (void *)file_node_ptr); // Do the parsing - if (XML_Parse(my_parser, (const char *)buffer, length, true) != XML_STATUS_OK) + if (XML_Parse(my_parser, buffer, length, true) != XML_STATUS_OK) { LL_WARNS() << "Error parsing xml error code: " << XML_ErrorString(XML_GetErrorCode(my_parser)) @@ -824,18 +846,20 @@ bool LLXMLNode::isFullyDefault() } // static -bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root, - const std::vector& paths) +bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root, const std::vector& paths, bool cacheable) { - 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, NULL)) + + if (!LLXMLNode::parseFile(filename, root, nullptr, cacheable)) { 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 d5b8b36d86..32aee057ed 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -126,34 +126,34 @@ public: bool isNull(); bool deleteChild(LLXMLNode* child); - void addChild(LLXMLNodePtr& new_child); + void addChild(LLXMLNodePtr& new_child); void setParent(LLXMLNodePtr& new_parent); // reparent if necessary - // Serialization + // Deserialization static bool parseFile( const std::string& filename, - LLXMLNodePtr& node, - LLXMLNode* defaults_tree); + LLXMLNodePtr& node, + LLXMLNode* defaults_tree, + bool cacheable = false); static bool parseBuffer( - U8* buffer, + const char* buffer, U32 length, - LLXMLNodePtr& node, + 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); - - + + static bool getLayeredXMLNode(LLXMLNodePtr& root, const std::vector& paths, bool cacheable = false); + // 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); } diff --git a/indra/llxml/llxmltree.cpp b/indra/llxml/llxmltree.cpp index be3bcf2a66..38321847c3 100644 --- a/indra/llxml/llxmltree.cpp +++ b/indra/llxml/llxmltree.cpp @@ -35,6 +35,7 @@ #include "v4math.h" #include "llquaternion.h" #include "lluuid.h" +#include "lldir.h" ////////////////////////////////////////////////////////////// // LLXmlTree @@ -60,20 +61,37 @@ 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); -bool LLXmlTree::parseFile(const std::string &path, bool keep_contents) + return success; +} + +bool LLXmlTree::parseString(const std::string &xml, bool keep_contents) { delete mRoot; mRoot = NULL; LLXmlTreeParser parser(this); - bool success = parser.parseFile( path, &mRoot, keep_contents ); - if( !success ) + bool success = parser.parseString(xml, &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; } @@ -536,6 +554,27 @@ 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 5d15c4c7f5..d47f26f731 100644 --- a/indra/llxml/llxmltree.h +++ b/indra/llxml/llxmltree.h @@ -56,6 +56,7 @@ 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; } @@ -199,7 +200,8 @@ public: LLXmlTreeParser(LLXmlTree* tree); virtual ~LLXmlTreeParser(); - bool parseFile(const std::string &path, LLXmlTreeNode** root, bool keep_contents ); + bool parseFile(const std::string &path, LLXmlTreeNode** root, bool keep_contents); + bool parseString(const std::string &xml, LLXmlTreeNode** root, bool keep_contents); protected: const std::string& tabs(); -- cgit v1.2.3 From 0868427913e0a1411bc857b227dad82414e42457 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Mon, 29 Apr 2024 16:24:43 +0300 Subject: Allow changing debug settings via Lua script --- indra/llxml/llcontrol.cpp | 4 ++-- indra/llxml/llcontrol.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index 2960ecf829..a2178ed77d 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -730,7 +730,7 @@ void LLControlGroup::setLLSD(const std::string& name, const LLSD& val) set(name, val); } -void LLControlGroup::setUntypedValue(const std::string& name, const LLSD& val) +void LLControlGroup::setUntypedValue(const std::string& name, const LLSD& val, bool saved_value) { if (name.empty()) { @@ -741,7 +741,7 @@ void LLControlGroup::setUntypedValue(const std::string& name, const LLSD& val) if (control) { - control->setValue(val); + control->setValue(val, saved_value); } else { diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 0839c02c50..7e79e2f31e 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -278,7 +278,7 @@ public: void setLLSD(const std::string& name, const LLSD& val); // type agnostic setter that takes LLSD - void setUntypedValue(const std::string& name, const LLSD& val); + void setUntypedValue(const std::string& name, const LLSD& val, bool saved_value = true); // generic setter template void set(const std::string& name, const T& val) -- cgit v1.2.3 From 79dca07d790a47db192099bcb85e740676a643ee Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 1 May 2024 19:58:47 +0300 Subject: Use LLViewerControlListener to access debug settings --- indra/llxml/llcontrol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 7e79e2f31e..5a8d688892 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -143,7 +143,7 @@ public: LLSD getDefault() const { return mValues.front(); } LLSD getSaveValue() const; - void set(const LLSD& val) { setValue(val); } + void set(const LLSD& val, bool saved_value = true) { setValue(val, saved_value); } void setValue(const LLSD& value, bool saved_value = TRUE); void setDefaultValue(const LLSD& value); void setPersist(ePersist); -- cgit v1.2.3 From f9473e8afcb624cc1b101195bf15943ec372b56f Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Mon, 6 May 2024 16:52:34 +0200 Subject: secondlife/viewer#1333 BOOL to bool conversion leftovers: ternaries --- indra/llxml/llcontrol.cpp | 12 ++++++------ indra/llxml/llxmltree.cpp | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index 6b7f63c192..952ad3e8cd 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -210,7 +210,7 @@ LLSD LLControlVariable::getComparableValue(const LLSD& value) void LLControlVariable::setValue(const LLSD& new_value, bool saved_value) { - if (mValidateSignal(this, new_value) == false) + if (!mValidateSignal(this, new_value)) { // can not set new value, exit return; @@ -218,12 +218,12 @@ void LLControlVariable::setValue(const LLSD& new_value, bool saved_value) LLSD storable_value = getComparableValue(new_value); LLSD original_value = getValue(); - bool value_changed = llsd_compare(original_value, storable_value) == false; + bool value_changed = !llsd_compare(original_value, storable_value); if(saved_value) { // If we're going to save this value, return to default but don't fire resetToDefault(false); - if (llsd_compare(mValues.back(), storable_value) == false) + if (!llsd_compare(mValues.back(), storable_value)) { mValues.push_back(storable_value); } @@ -233,7 +233,7 @@ void LLControlVariable::setValue(const LLSD& new_value, bool saved_value) // This is an unsaved value. Its needs to reside at // mValues[2] (or greater). It must not affect // the result of getSaveValue() - if (llsd_compare(mValues.back(), storable_value) == false) + if (!llsd_compare(mValues.back(), storable_value)) { while(mValues.size() > 2) { @@ -267,10 +267,10 @@ void LLControlVariable::setDefaultValue(const LLSD& value) LLSD comparable_value = getComparableValue(value); LLSD original_value = getValue(); - bool value_changed = (llsd_compare(original_value, comparable_value) == false); + bool value_changed = !llsd_compare(original_value, comparable_value); resetToDefault(false); mValues[0] = comparable_value; - if(value_changed) + if (value_changed) { firePropertyChanged(original_value); } diff --git a/indra/llxml/llxmltree.cpp b/indra/llxml/llxmltree.cpp index 38321847c3..0c1615f486 100644 --- a/indra/llxml/llxmltree.cpp +++ b/indra/llxml/llxmltree.cpp @@ -155,14 +155,14 @@ void LLXmlTreeNode::dump( const std::string& prefix ) bool LLXmlTreeNode::hasAttribute(const std::string& name) { - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString(name); attribute_map_t::iterator iter = mAttributes.find(canonical_name); - return (iter == mAttributes.end()) ? false : true; + return iter != mAttributes.end(); } void LLXmlTreeNode::addAttribute(const std::string& name, const std::string& value) { - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString(name); const std::string *newstr = new std::string(value); mAttributes[canonical_name] = newstr; // insert + copy } -- cgit v1.2.3 From ad6425173900855852b8c8437cc88120ea46cc53 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 7 May 2024 20:44:53 +0300 Subject: viewer#1420 Fixed names not showing in Chat Save node prior to calling updateDefault --- indra/llxml/llxmlnode.cpp | 46 +++++++++++++++++++++++++++++++++------------- indra/llxml/llxmlnode.h | 16 ++++++++++------ 2 files changed, 43 insertions(+), 19 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 627e99a1e6..dc60b1aa66 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() +LLXMLNodePtr LLXMLNode::deepCopy() const { LLXMLNodePtr newnode = LLXMLNodePtr(new LLXMLNode(*this)); if (mChildren.notNull()) { - for (LLXMLChildList::iterator iter = mChildren->map.begin(); + for (LLXMLChildList::const_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::iterator iter = mAttributes.begin(); + for (LLXMLAttribList::const_iterator iter = mAttributes.begin(); iter != mAttributes.end(); ++iter) { LLXMLNodePtr temp_ptr_for_gcc(iter->second->deepCopy()); @@ -653,10 +653,12 @@ bool LLXMLNode::updateNode( static std::map sXMLCache; static LLSharedMutex sXMLCacheMutex; -static void saveToCache(const std::string& filename, LLXMLNodePtr& node) +static void saveToCache(const std::string& filename, const LLXMLNodePtr& node) { + LLXMLNodePtr node_copy = node->deepCopy(); + LLExclusiveMutexLock lock(&sXMLCacheMutex); - sXMLCache.emplace(filename, node.notNull() ? node->deepCopy() : nullptr); + sXMLCache.emplace(filename, node_copy); } static bool loadFromCache(const std::string& filename, LLXMLNodePtr& node) @@ -665,8 +667,8 @@ static bool loadFromCache(const std::string& filename, LLXMLNodePtr& node) auto it = sXMLCache.find(filename); if (it == sXMLCache.end()) return false; - node = it->second.notNull() ? it->second->deepCopy() : nullptr; - return node.notNull(); + node = it->second->deepCopy(); + return true; } // static @@ -676,7 +678,11 @@ bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXML if (cacheable) { if (loadFromCache(filename, node)) + { + node->setDefault(defaults_tree); + node->updateDefault(); return true; + } } std::string xml = gDirUtilp->getFileContents(filename); @@ -684,12 +690,14 @@ bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXML { LL_WARNS("XMLNode") << "no XML file: " << filename << LL_ENDL; } - else if (parseBuffer(xml.data(), xml.size(), node, defaults_tree)) + else if (parseBuffer(xml.data(), xml.size(), node)) { if (cacheable) { saveToCache(filename, node); } + node->setDefault(defaults_tree); + node->updateDefault(); return true; } @@ -697,12 +705,27 @@ bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXML return false; } +// 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; +} + // static bool LLXMLNode::parseBuffer( const char* buffer, U32 length, - LLXMLNodePtr& node, - LLXMLNode* defaults) + LLXMLNodePtr& node) { // Init XML_Parser my_parser = XML_ParserCreate(NULL); @@ -739,9 +762,6 @@ bool LLXMLNode::parseBuffer( LLXMLNode *return_node = file_node->mChildren->map.begin()->second; - return_node->setDefault(defaults); - return_node->updateDefault(); - node = return_node; return true; } diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index 32aee057ed..e09c89c543 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -121,7 +121,7 @@ public: LLXMLNode(const char* name, bool is_attribute); LLXMLNode(LLStringTableEntry* name, bool is_attribute); LLXMLNode(const LLXMLNode& rhs); - LLXMLNodePtr deepCopy(); + LLXMLNodePtr deepCopy() const; bool isNull(); @@ -135,11 +135,11 @@ public: LLXMLNodePtr& node, LLXMLNode* defaults_tree, bool cacheable = false); - static bool parseBuffer( - const char* buffer, - U32 length, - LLXMLNodePtr& node, - LLXMLNode* defaults); + static bool parseBuffer( + const char* buffer, + U32 length, + LLXMLNodePtr& node, + LLXMLNode* defaults); static bool parseStream( std::istream& str, LLXMLNodePtr& node, @@ -290,6 +290,10 @@ 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 -- cgit v1.2.3 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 From c3da5bb12d1c7c173929433589a4068555791bea Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 15 May 2024 09:11:29 -0400 Subject: Manual whitespace fixes (fix_whitespace.py). --- indra/llxml/llcontrol.cpp | 1830 ++++++++++++++++++++++----------------------- indra/llxml/llcontrol.h | 614 +++++++-------- 2 files changed, 1222 insertions(+), 1222 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index a2178ed77d..1194e0c3bc 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llcontrol.cpp * @brief Holds global state for viewer. * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -109,60 +109,60 @@ std::string SETTINGS_PROFILE = "settings_profile.log"; bool LLControlVariable::llsd_compare(const LLSD& a, const LLSD & b) { - bool result = false; - switch (mType) - { - case TYPE_U32: - case TYPE_S32: - result = a.asInteger() == b.asInteger(); - break; - case TYPE_BOOLEAN: - result = a.asBoolean() == b.asBoolean(); - break; - case TYPE_F32: - result = a.asReal() == b.asReal(); - break; - case TYPE_VEC3: - case TYPE_VEC3D: - result = LLVector3d(a) == LLVector3d(b); - break; - case TYPE_QUAT: - result = LLQuaternion(a) == LLQuaternion(b); - break; - case TYPE_RECT: - result = LLRect(a) == LLRect(b); - break; - case TYPE_COL4: - result = LLColor4(a) == LLColor4(b); - break; - case TYPE_COL3: - result = LLColor3(a) == LLColor3(b); - break; - case TYPE_STRING: - result = a.asString() == b.asString(); - break; - default: - break; - } - - return result; + bool result = false; + switch (mType) + { + case TYPE_U32: + case TYPE_S32: + result = a.asInteger() == b.asInteger(); + break; + case TYPE_BOOLEAN: + result = a.asBoolean() == b.asBoolean(); + break; + case TYPE_F32: + result = a.asReal() == b.asReal(); + break; + case TYPE_VEC3: + case TYPE_VEC3D: + result = LLVector3d(a) == LLVector3d(b); + break; + case TYPE_QUAT: + result = LLQuaternion(a) == LLQuaternion(b); + break; + case TYPE_RECT: + result = LLRect(a) == LLRect(b); + break; + case TYPE_COL4: + result = LLColor4(a) == LLColor4(b); + break; + case TYPE_COL3: + result = LLColor3(a) == LLColor3(b); + break; + case TYPE_STRING: + result = a.asString() == b.asString(); + break; + default: + break; + } + + return result; } LLControlVariable::LLControlVariable(const std::string& name, eControlType type, - LLSD initial, const std::string& comment, - ePersist persist, bool hidefromsettingseditor) - : mName(name), - mComment(comment), - mType(type), - mPersist(persist), - mHideFromSettingsEditor(hidefromsettingseditor) -{ - if ((persist != PERSIST_NO) && mComment.empty()) - { - LL_ERRS() << "Must supply a comment for control " << mName << LL_ENDL; - } - //Push back versus setValue'ing here, since we don't want to call a signal yet - mValues.push_back(initial); + LLSD initial, const std::string& comment, + ePersist persist, bool hidefromsettingseditor) + : mName(name), + mComment(comment), + mType(type), + mPersist(persist), + mHideFromSettingsEditor(hidefromsettingseditor) +{ + if ((persist != PERSIST_NO) && mComment.empty()) + { + LL_ERRS() << "Must supply a comment for control " << mName << LL_ENDL; + } + //Push back versus setValue'ing here, since we don't want to call a signal yet + mValues.push_back(initial); } @@ -173,70 +173,70 @@ LLControlVariable::~LLControlVariable() LLSD LLControlVariable::getComparableValue(const LLSD& value) { - // *FIX:MEP - The following is needed to make the LLSD::ImplString - // work with boolean controls... - LLSD storable_value; - if(TYPE_BOOLEAN == type() && value.isString()) - { - BOOL temp; - if(LLStringUtil::convertToBOOL(value.asString(), temp)) - { - storable_value = (bool)temp; - } - else - { - storable_value = false; - } - } - else if (TYPE_LLSD == type() && value.isString()) - { - LLPointer parser = new LLSDNotationParser; - LLSD result; - std::stringstream value_stream(value.asString()); - if (parser->parse(value_stream, result, LLSDSerialize::SIZE_UNLIMITED) != LLSDParser::PARSE_FAILURE) - { - storable_value = result; - } - else - { - storable_value = value; - } - } - else - { - storable_value = value; - } - - return storable_value; + // *FIX:MEP - The following is needed to make the LLSD::ImplString + // work with boolean controls... + LLSD storable_value; + if(TYPE_BOOLEAN == type() && value.isString()) + { + BOOL temp; + if(LLStringUtil::convertToBOOL(value.asString(), temp)) + { + storable_value = (bool)temp; + } + else + { + storable_value = false; + } + } + else if (TYPE_LLSD == type() && value.isString()) + { + LLPointer parser = new LLSDNotationParser; + LLSD result; + std::stringstream value_stream(value.asString()); + if (parser->parse(value_stream, result, LLSDSerialize::SIZE_UNLIMITED) != LLSDParser::PARSE_FAILURE) + { + storable_value = result; + } + else + { + storable_value = value; + } + } + else + { + storable_value = value; + } + + return storable_value; } void LLControlVariable::setValue(const LLSD& new_value, bool saved_value) { - if (mValidateSignal(this, new_value) == false) - { - // can not set new value, exit - return; - } - - LLSD storable_value = getComparableValue(new_value); - LLSD original_value = getValue(); - bool value_changed = llsd_compare(original_value, storable_value) == FALSE; - if(saved_value) - { - // If we're going to save this value, return to default but don't fire - resetToDefault(false); - if (llsd_compare(mValues.back(), storable_value) == FALSE) - { - mValues.push_back(storable_value); - } - } + if (mValidateSignal(this, new_value) == false) + { + // can not set new value, exit + return; + } + + LLSD storable_value = getComparableValue(new_value); + LLSD original_value = getValue(); + bool value_changed = llsd_compare(original_value, storable_value) == FALSE; + if(saved_value) + { + // If we're going to save this value, return to default but don't fire + resetToDefault(false); + if (llsd_compare(mValues.back(), storable_value) == FALSE) + { + mValues.push_back(storable_value); + } + } else { // This is an unsaved value. Its needs to reside at - // mValues[2] (or greater). It must not affect + // mValues[2] (or greater). It must not affect // the result of getSaveValue() - if (llsd_compare(mValues.back(), storable_value) == FALSE) - { + if (llsd_compare(mValues.back(), storable_value) == FALSE) + { while(mValues.size() > 2) { // Remove any unsaved values. @@ -251,107 +251,107 @@ void LLControlVariable::setValue(const LLSD& new_value, bool saved_value) // Add the 'un-save' value. mValues.push_back(storable_value); - } + } } if(value_changed) { - firePropertyChanged(original_value); + firePropertyChanged(original_value); } } void LLControlVariable::setDefaultValue(const LLSD& value) { - // Set the control variables value and make it - // the default value. If the active value is changed, - // send the signal. - // *NOTE: Default values are not saved, only read. + // Set the control variables value and make it + // the default value. If the active value is changed, + // send the signal. + // *NOTE: Default values are not saved, only read. - LLSD comparable_value = getComparableValue(value); - LLSD original_value = getValue(); - bool value_changed = (llsd_compare(original_value, comparable_value) == FALSE); - resetToDefault(false); - mValues[0] = comparable_value; - if(value_changed) - { - firePropertyChanged(original_value); - } + LLSD comparable_value = getComparableValue(value); + LLSD original_value = getValue(); + bool value_changed = (llsd_compare(original_value, comparable_value) == FALSE); + resetToDefault(false); + mValues[0] = comparable_value; + if(value_changed) + { + firePropertyChanged(original_value); + } } void LLControlVariable::setPersist(ePersist state) { - mPersist = state; + mPersist = state; } void LLControlVariable::setHiddenFromSettingsEditor(bool hide) { - mHideFromSettingsEditor = hide; + mHideFromSettingsEditor = hide; } void LLControlVariable::setComment(const std::string& comment) { - mComment = comment; + mComment = comment; } void LLControlVariable::resetToDefault(bool fire_signal) { - //The first setting is always the default - //Pop to it and fire off the listener - LLSD originalValue = mValues.back(); + //The first setting is always the default + //Pop to it and fire off the listener + LLSD originalValue = mValues.back(); - while(mValues.size() > 1) - { - mValues.pop_back(); - } - - if(fire_signal) - { - firePropertyChanged(originalValue); - } + while(mValues.size() > 1) + { + mValues.pop_back(); + } + + if(fire_signal) + { + firePropertyChanged(originalValue); + } } bool LLControlVariable::shouldSave(bool nondefault_only) { - // This method is used to decide whether we should save a given - // variable. Two of the three values of mPersist are easy. - if (mPersist == PERSIST_NO) - return false; + // This method is used to decide whether we should save a given + // variable. Two of the three values of mPersist are easy. + if (mPersist == PERSIST_NO) + return false; - if (mPersist == PERSIST_ALWAYS) - return true; + if (mPersist == PERSIST_ALWAYS) + return true; - // PERSIST_NONDFT - // If caller doesn't need us to filter, just save. - if (! nondefault_only) - return true; + // PERSIST_NONDFT + // If caller doesn't need us to filter, just save. + if (! nondefault_only) + return true; - // PERSIST_NONDFT: caller only wants us to save this variable if its value - // differs from default. - if (isDefault()) // never been altered - return false; + // PERSIST_NONDFT: caller only wants us to save this variable if its value + // differs from default. + if (isDefault()) // never been altered + return false; - // We've set at least one other value: compare it to default. Save only if - // they differ. - return ! llsd_compare(getSaveValue(), getDefault()); + // We've set at least one other value: compare it to default. Save only if + // they differ. + return ! llsd_compare(getSaveValue(), getDefault()); } LLSD LLControlVariable::getSaveValue() const { - //The first level of the stack is default - //We assume that the second level is user preferences that should be saved - if(mValues.size() > 1) return mValues[1]; - return mValues[0]; + //The first level of the stack is default + //We assume that the second level is user preferences that should be saved + if(mValues.size() > 1) return mValues[1]; + return mValues[0]; } LLPointer LLControlGroup::getControl(const std::string& name) { - if (mSettingsProfile) - { - incrCount(name); - } + if (mSettingsProfile) + { + incrCount(name); + } - ctrl_name_table_t::iterator iter = mNameTable.find(name); - return iter == mNameTable.end() ? LLPointer() : iter->second; + ctrl_name_table_t::iterator iter = mNameTable.find(name); + return iter == mNameTable.end() ? LLPointer() : iter->second; } @@ -373,296 +373,296 @@ const std::string LLControlGroup::mTypeString[TYPE_COUNT] = { "U32" }; LLControlGroup::LLControlGroup(const std::string& name) -: LLInstanceTracker(name), - mSettingsProfile(false) +: LLInstanceTracker(name), + mSettingsProfile(false) { - if (NULL != getenv("LL_SETTINGS_PROFILE")) - { - mSettingsProfile = true; - } + if (NULL != getenv("LL_SETTINGS_PROFILE")) + { + mSettingsProfile = true; + } } LLControlGroup::~LLControlGroup() { - cleanup(); + cleanup(); } static bool compareRoutine(settings_pair_t lhs, settings_pair_t rhs) { - return lhs.second > rhs.second; + return lhs.second > rhs.second; }; void LLControlGroup::cleanup() { - if(mSettingsProfile && getCount.size() != 0) - { - std::string file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, SETTINGS_PROFILE); - LLFILE* out = LLFile::fopen(file, "w"); /* Flawfinder: ignore */ - if(!out) - { - LL_WARNS("SettingsProfile") << "Error opening " << SETTINGS_PROFILE << LL_ENDL; - } - else - { - F64 end_time = LLTimer::getTotalSeconds(); - U32 total_seconds = (U32)(end_time - start_time); - - std::string msg = llformat("Runtime (seconds): %d\n\n No. accesses Avg. accesses/sec Name\n", total_seconds); - std::ostringstream data_msg; - - data_msg << msg; - size_t data_size = data_msg.str().size(); - if (fwrite(data_msg.str().c_str(), 1, data_size, out) != data_size) - { - LL_WARNS("SettingsProfile") << "Failed to write settings profile header" << LL_ENDL; - } - - for (LLSD::map_const_iterator iter = getCount.beginMap(); iter != getCount.endMap(); ++iter) - { - getCount_v.push_back(settings_pair_t(iter->first, iter->second.asInteger())); - } - sort(getCount_v.begin(), getCount_v.end(), compareRoutine); - - for (settings_vec_t::iterator iter = getCount_v.begin(); iter != getCount_v.end(); ++iter) - { - U32 access_rate = 0; - if (total_seconds != 0) - { - access_rate = iter->second / total_seconds; - } - if (access_rate >= 2) - { - std::ostringstream data_msg; - msg = llformat("%13d %7d %s", iter->second, access_rate, iter->first.c_str()); - data_msg << msg << "\n"; - size_t data_size = data_msg.str().size(); - if (fwrite(data_msg.str().c_str(), 1, data_size, out) != data_size) - { - LL_WARNS("SettingsProfile") << "Failed to write settings profile" << LL_ENDL; - } - } - } - getCount = LLSD::emptyMap(); - fclose(out); - } - } - - mNameTable.clear(); + if(mSettingsProfile && getCount.size() != 0) + { + std::string file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, SETTINGS_PROFILE); + LLFILE* out = LLFile::fopen(file, "w"); /* Flawfinder: ignore */ + if(!out) + { + LL_WARNS("SettingsProfile") << "Error opening " << SETTINGS_PROFILE << LL_ENDL; + } + else + { + F64 end_time = LLTimer::getTotalSeconds(); + U32 total_seconds = (U32)(end_time - start_time); + + std::string msg = llformat("Runtime (seconds): %d\n\n No. accesses Avg. accesses/sec Name\n", total_seconds); + std::ostringstream data_msg; + + data_msg << msg; + size_t data_size = data_msg.str().size(); + if (fwrite(data_msg.str().c_str(), 1, data_size, out) != data_size) + { + LL_WARNS("SettingsProfile") << "Failed to write settings profile header" << LL_ENDL; + } + + for (LLSD::map_const_iterator iter = getCount.beginMap(); iter != getCount.endMap(); ++iter) + { + getCount_v.push_back(settings_pair_t(iter->first, iter->second.asInteger())); + } + sort(getCount_v.begin(), getCount_v.end(), compareRoutine); + + for (settings_vec_t::iterator iter = getCount_v.begin(); iter != getCount_v.end(); ++iter) + { + U32 access_rate = 0; + if (total_seconds != 0) + { + access_rate = iter->second / total_seconds; + } + if (access_rate >= 2) + { + std::ostringstream data_msg; + msg = llformat("%13d %7d %s", iter->second, access_rate, iter->first.c_str()); + data_msg << msg << "\n"; + size_t data_size = data_msg.str().size(); + if (fwrite(data_msg.str().c_str(), 1, data_size, out) != data_size) + { + LL_WARNS("SettingsProfile") << "Failed to write settings profile" << LL_ENDL; + } + } + } + getCount = LLSD::emptyMap(); + fclose(out); + } + } + + mNameTable.clear(); } eControlType LLControlGroup::typeStringToEnum(const std::string& typestr) { - for(int i = 0; i < (int)TYPE_COUNT; ++i) - { - if(mTypeString[i] == typestr) return (eControlType)i; - } - return (eControlType)-1; + for(int i = 0; i < (int)TYPE_COUNT; ++i) + { + if(mTypeString[i] == typestr) return (eControlType)i; + } + return (eControlType)-1; } std::string LLControlGroup::typeEnumToString(eControlType typeenum) { - return mTypeString[typeenum]; + return mTypeString[typeenum]; } LLControlVariable* LLControlGroup::declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, BOOL hidefromsettingseditor) { - LLControlVariable* existing_control = getControl(name); - if (existing_control) - { - if ((persist != LLControlVariable::PERSIST_NO) && existing_control->isType(type)) - { - if (!existing_control->llsd_compare(existing_control->getDefault(), initial_val)) - { - // Sometimes we need to declare a control *after* it has been loaded from a settings file. - LLSD cur_value = existing_control->getValue(); // get the current value - existing_control->setDefaultValue(initial_val); // set the default to the declared value - existing_control->setValue(cur_value); // now set to the loaded value - } - } - else - { - LL_WARNS("Settings") << "Control named " << name << " already exists, ignoring new declaration." << LL_ENDL; - } - return existing_control; - } - - // if not, create the control and add it to the name table - LLControlVariable* control = new LLControlVariable(name, type, initial_val, comment, persist, hidefromsettingseditor); - mNameTable[name] = control; - return control; + LLControlVariable* existing_control = getControl(name); + if (existing_control) + { + if ((persist != LLControlVariable::PERSIST_NO) && existing_control->isType(type)) + { + if (!existing_control->llsd_compare(existing_control->getDefault(), initial_val)) + { + // Sometimes we need to declare a control *after* it has been loaded from a settings file. + LLSD cur_value = existing_control->getValue(); // get the current value + existing_control->setDefaultValue(initial_val); // set the default to the declared value + existing_control->setValue(cur_value); // now set to the loaded value + } + } + else + { + LL_WARNS("Settings") << "Control named " << name << " already exists, ignoring new declaration." << LL_ENDL; + } + return existing_control; + } + + // if not, create the control and add it to the name table + LLControlVariable* control = new LLControlVariable(name, type, initial_val, comment, persist, hidefromsettingseditor); + mNameTable[name] = control; + return control; } LLControlVariable* LLControlGroup::declareU32(const std::string& name, const U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist) { - return declareControl(name, TYPE_U32, (LLSD::Integer) initial_val, comment, persist); + return declareControl(name, TYPE_U32, (LLSD::Integer) initial_val, comment, persist); } LLControlVariable* LLControlGroup::declareS32(const std::string& name, const S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist) { - return declareControl(name, TYPE_S32, initial_val, comment, persist); + return declareControl(name, TYPE_S32, initial_val, comment, persist); } LLControlVariable* LLControlGroup::declareF32(const std::string& name, const F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist) { - return declareControl(name, TYPE_F32, initial_val, comment, persist); + return declareControl(name, TYPE_F32, initial_val, comment, persist); } LLControlVariable* LLControlGroup::declareBOOL(const std::string& name, const BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist) { - return declareControl(name, TYPE_BOOLEAN, initial_val, comment, persist); + return declareControl(name, TYPE_BOOLEAN, initial_val, comment, persist); } LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string& initial_val, const std::string& comment, LLControlVariable::ePersist persist) { - return declareControl(name, TYPE_STRING, initial_val, comment, persist); + return declareControl(name, TYPE_STRING, initial_val, comment, persist); } LLControlVariable* LLControlGroup::declareVec3(const std::string& name, const LLVector3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist) { - return declareControl(name, TYPE_VEC3, initial_val.getValue(), comment, persist); + return declareControl(name, TYPE_VEC3, initial_val.getValue(), comment, persist); } LLControlVariable* LLControlGroup::declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist) { - return declareControl(name, TYPE_VEC3D, initial_val.getValue(), comment, persist); + return declareControl(name, TYPE_VEC3D, initial_val.getValue(), comment, persist); } LLControlVariable* LLControlGroup::declareQuat(const std::string& name, const LLQuaternion &initial_val, const std::string& comment, LLControlVariable::ePersist persist) { - return declareControl(name, TYPE_QUAT, initial_val.getValue(), comment, persist); + return declareControl(name, TYPE_QUAT, initial_val.getValue(), comment, persist); } LLControlVariable* LLControlGroup::declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist) { - return declareControl(name, TYPE_RECT, initial_val.getValue(), comment, persist); + return declareControl(name, TYPE_RECT, initial_val.getValue(), comment, persist); } LLControlVariable* LLControlGroup::declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist ) { - return declareControl(name, TYPE_COL4, initial_val.getValue(), comment, persist); + return declareControl(name, TYPE_COL4, initial_val.getValue(), comment, persist); } LLControlVariable* LLControlGroup::declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist ) { - return declareControl(name, TYPE_COL3, initial_val.getValue(), comment, persist); + return declareControl(name, TYPE_COL3, initial_val.getValue(), comment, persist); } LLControlVariable* LLControlGroup::declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, LLControlVariable::ePersist persist ) { - return declareControl(name, TYPE_LLSD, initial_val, comment, persist); + return declareControl(name, TYPE_LLSD, initial_val, comment, persist); } void LLControlGroup::incrCount(const std::string& name) { - if (0.0 == start_time) - { - start_time = LLTimer::getTotalSeconds(); - } - getCount[name] = getCount[name].asInteger() + 1; + if (0.0 == start_time) + { + start_time = LLTimer::getTotalSeconds(); + } + getCount[name] = getCount[name].asInteger() + 1; } BOOL LLControlGroup::getBOOL(const std::string& name) { - return (BOOL)get(name); + return (BOOL)get(name); } S32 LLControlGroup::getS32(const std::string& name) { - return get(name); + return get(name); } U32 LLControlGroup::getU32(const std::string& name) { - return get(name); + return get(name); } F32 LLControlGroup::getF32(const std::string& name) { - return get(name); + return get(name); } std::string LLControlGroup::getString(const std::string& name) { - return get(name); + return get(name); } LLWString LLControlGroup::getWString(const std::string& name) { - return get(name); + return get(name); } std::string LLControlGroup::getText(const std::string& name) { - std::string utf8_string = getString(name); - LLStringUtil::replaceChar(utf8_string, '^', '\n'); - LLStringUtil::replaceChar(utf8_string, '%', ' '); - return (utf8_string); + std::string utf8_string = getString(name); + LLStringUtil::replaceChar(utf8_string, '^', '\n'); + LLStringUtil::replaceChar(utf8_string, '%', ' '); + return (utf8_string); } LLVector3 LLControlGroup::getVector3(const std::string& name) { - return get(name); + return get(name); } LLVector3d LLControlGroup::getVector3d(const std::string& name) { - return get(name); + return get(name); } LLQuaternion LLControlGroup::getQuaternion(const std::string& name) { - return get(name); + return get(name); } LLRect LLControlGroup::getRect(const std::string& name) { - return get(name); + return get(name); } LLColor4 LLControlGroup::getColor(const std::string& name) { - return get(name); + return get(name); } LLColor4 LLControlGroup::getColor4(const std::string& name) { - return get(name); + return get(name); } LLColor3 LLControlGroup::getColor3(const std::string& name) { - return get(name); + return get(name); } LLSD LLControlGroup::getLLSD(const std::string& name) { - return get(name); + return get(name); } LLSD LLControlGroup::asLLSD(bool diffs_only) { - // Dump all stored values as LLSD - LLSD result = LLSD::emptyArray(); - for (ctrl_name_table_t::iterator iter = mNameTable.begin(); - iter != mNameTable.end(); iter++) - { - LLControlVariable *control = iter->second; - if (!control || control->isType(TYPE_STRING) || (diffs_only && control->isDefault())) - { - continue; - } - const std::string& name = iter->first; - result[name] = getLLSD(name); - } - return result; + // Dump all stored values as LLSD + LLSD result = LLSD::emptyArray(); + for (ctrl_name_table_t::iterator iter = mNameTable.begin(); + iter != mNameTable.end(); iter++) + { + LLControlVariable *control = iter->second; + if (!control || control->isType(TYPE_STRING) || (diffs_only && control->isDefault())) + { + continue; + } + const std::string& name = iter->first; + result[name] = getLLSD(name); + } + return result; } BOOL LLControlGroup::controlExists(const std::string& name) { - ctrl_name_table_t::iterator iter = mNameTable.find(name); - return iter != mNameTable.end(); + ctrl_name_table_t::iterator iter = mNameTable.find(name); + return iter != mNameTable.end(); } @@ -672,81 +672,81 @@ BOOL LLControlGroup::controlExists(const std::string& name) void LLControlGroup::setBOOL(const std::string& name, BOOL val) { - set(name, val); + set(name, val); } void LLControlGroup::setS32(const std::string& name, S32 val) { - set(name, val); + set(name, val); } void LLControlGroup::setF32(const std::string& name, F32 val) { - set(name, val); + set(name, val); } void LLControlGroup::setU32(const std::string& name, U32 val) { - set(name, val); + set(name, val); } void LLControlGroup::setString(const std::string& name, const std::string &val) { - set(name, val); + set(name, val); } void LLControlGroup::setVector3(const std::string& name, const LLVector3 &val) { - set(name, val); + set(name, val); } void LLControlGroup::setVector3d(const std::string& name, const LLVector3d &val) { - set(name, val); + set(name, val); } void LLControlGroup::setQuaternion(const std::string& name, const LLQuaternion &val) { - set(name, val); + set(name, val); } void LLControlGroup::setRect(const std::string& name, const LLRect &val) { - set(name, val); + set(name, val); } void LLControlGroup::setColor4(const std::string& name, const LLColor4 &val) { - set(name, val); + set(name, val); } void LLControlGroup::setLLSD(const std::string& name, const LLSD& val) { - set(name, val); + set(name, val); } void LLControlGroup::setUntypedValue(const std::string& name, const LLSD& val, bool saved_value) { - if (name.empty()) - { - return; - } + if (name.empty()) + { + return; + } + + LLControlVariable* control = getControl(name); - LLControlVariable* control = getControl(name); - - if (control) - { - control->setValue(val, saved_value); - } - else - { - CONTROL_ERRS << "Invalid control " << name << LL_ENDL; - } + if (control) + { + control->setValue(val, saved_value); + } + else + { + CONTROL_ERRS << "Invalid control " << name << LL_ENDL; + } } @@ -757,388 +757,388 @@ void LLControlGroup::setUntypedValue(const std::string& name, const LLSD& val, b // Returns number of controls loaded, so 0 if failure U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require_declaration, eControlType declare_as) { - std::string name; - - LLXmlTree xml_controls; - - if (!xml_controls.parseFile(filename)) - { - LL_WARNS("Settings") << "Unable to open control file " << filename << LL_ENDL; - return 0; - } - - LLXmlTreeNode* rootp = xml_controls.getRoot(); - if (!rootp || !rootp->hasAttribute("version")) - { - LL_WARNS("Settings") << "No valid settings header found in control file " << filename << LL_ENDL; - return 0; - } - - U32 validitems = 0; - S32 version; - - rootp->getAttributeS32("version", version); - - // Check file version - if (version != CURRENT_VERSION) - { - LL_INFOS("Settings") << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << LL_ENDL; - return 0; - } - - LLXmlTreeNode* child_nodep = rootp->getFirstChild(); - while(child_nodep) - { - name = child_nodep->getName(); - - BOOL declared = controlExists(name); - - if (require_declaration && !declared) - { - // Declaration required, but this name not declared. - // Complain about non-empty names. - if (!name.empty()) - { - //read in to end of line - LL_WARNS("Settings") << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << LL_ENDL; - } - child_nodep = rootp->getNextChild(); - continue; - } - - // Got an item. Load it up. - // If not declared, assume it's a string - if (!declared) - { - switch(declare_as) - { - case TYPE_COL4: - declareColor4(name, LLColor4::white, LLStringUtil::null, LLControlVariable::PERSIST_NO); - break; - case TYPE_STRING: - default: - declareString(name, LLStringUtil::null, LLStringUtil::null, LLControlVariable::PERSIST_NO); - break; - } - } - - // Control name has been declared in code. - LLControlVariable *control = getControl(name); - - llassert(control); - - switch(control->mType) - { - case TYPE_F32: - { - F32 initial = 0.f; - - child_nodep->getAttributeF32("value", initial); - - control->set(initial); - validitems++; - } - break; - case TYPE_S32: - { - S32 initial = 0; - - child_nodep->getAttributeS32("value", initial); - - control->set(initial); - validitems++; - } - break; - case TYPE_U32: - { - U32 initial = 0; - child_nodep->getAttributeU32("value", initial); - control->set((LLSD::Integer) initial); - validitems++; - } - break; - case TYPE_BOOLEAN: - { - BOOL initial = FALSE; - - child_nodep->getAttributeBOOL("value", initial); - control->set(initial); - - validitems++; - } - break; - case TYPE_STRING: - { - std::string string; - child_nodep->getAttributeString("value", string); - control->set(string); - validitems++; - } - break; - case TYPE_VEC3: - { - LLVector3 vector; - - child_nodep->getAttributeVector3("value", vector); - control->set(vector.getValue()); - validitems++; - } - break; - case TYPE_VEC3D: - { - LLVector3d vector; - - child_nodep->getAttributeVector3d("value", vector); - - control->set(vector.getValue()); - validitems++; - } - break; - case TYPE_QUAT: - { - LLQuaternion quat; - - child_nodep->getAttributeQuat("value", quat); - - control->set(quat.getValue()); - validitems++; - } - break; - case TYPE_RECT: - { - //RN: hack to support reading rectangles from a string - std::string rect_string; - - child_nodep->getAttributeString("value", rect_string); - std::istringstream istream(rect_string); - S32 left, bottom, width, height; - - istream >> left >> bottom >> width >> height; - - LLRect rect; - rect.setOriginAndSize(left, bottom, width, height); - - control->set(rect.getValue()); - validitems++; - } - break; - case TYPE_COL4: - { - LLColor4 color; - - child_nodep->getAttributeColor4("value", color); - control->set(color.getValue()); - validitems++; - } - break; - case TYPE_COL3: - { - LLVector3 color; - - child_nodep->getAttributeVector3("value", color); - control->set(LLColor3(color.mV).getValue()); - validitems++; - } - break; - - default: - break; - - } - - child_nodep = rootp->getNextChild(); - } - - return validitems; + std::string name; + + LLXmlTree xml_controls; + + if (!xml_controls.parseFile(filename)) + { + LL_WARNS("Settings") << "Unable to open control file " << filename << LL_ENDL; + return 0; + } + + LLXmlTreeNode* rootp = xml_controls.getRoot(); + if (!rootp || !rootp->hasAttribute("version")) + { + LL_WARNS("Settings") << "No valid settings header found in control file " << filename << LL_ENDL; + return 0; + } + + U32 validitems = 0; + S32 version; + + rootp->getAttributeS32("version", version); + + // Check file version + if (version != CURRENT_VERSION) + { + LL_INFOS("Settings") << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << LL_ENDL; + return 0; + } + + LLXmlTreeNode* child_nodep = rootp->getFirstChild(); + while(child_nodep) + { + name = child_nodep->getName(); + + BOOL declared = controlExists(name); + + if (require_declaration && !declared) + { + // Declaration required, but this name not declared. + // Complain about non-empty names. + if (!name.empty()) + { + //read in to end of line + LL_WARNS("Settings") << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << LL_ENDL; + } + child_nodep = rootp->getNextChild(); + continue; + } + + // Got an item. Load it up. + // If not declared, assume it's a string + if (!declared) + { + switch(declare_as) + { + case TYPE_COL4: + declareColor4(name, LLColor4::white, LLStringUtil::null, LLControlVariable::PERSIST_NO); + break; + case TYPE_STRING: + default: + declareString(name, LLStringUtil::null, LLStringUtil::null, LLControlVariable::PERSIST_NO); + break; + } + } + + // Control name has been declared in code. + LLControlVariable *control = getControl(name); + + llassert(control); + + switch(control->mType) + { + case TYPE_F32: + { + F32 initial = 0.f; + + child_nodep->getAttributeF32("value", initial); + + control->set(initial); + validitems++; + } + break; + case TYPE_S32: + { + S32 initial = 0; + + child_nodep->getAttributeS32("value", initial); + + control->set(initial); + validitems++; + } + break; + case TYPE_U32: + { + U32 initial = 0; + child_nodep->getAttributeU32("value", initial); + control->set((LLSD::Integer) initial); + validitems++; + } + break; + case TYPE_BOOLEAN: + { + BOOL initial = FALSE; + + child_nodep->getAttributeBOOL("value", initial); + control->set(initial); + + validitems++; + } + break; + case TYPE_STRING: + { + std::string string; + child_nodep->getAttributeString("value", string); + control->set(string); + validitems++; + } + break; + case TYPE_VEC3: + { + LLVector3 vector; + + child_nodep->getAttributeVector3("value", vector); + control->set(vector.getValue()); + validitems++; + } + break; + case TYPE_VEC3D: + { + LLVector3d vector; + + child_nodep->getAttributeVector3d("value", vector); + + control->set(vector.getValue()); + validitems++; + } + break; + case TYPE_QUAT: + { + LLQuaternion quat; + + child_nodep->getAttributeQuat("value", quat); + + control->set(quat.getValue()); + validitems++; + } + break; + case TYPE_RECT: + { + //RN: hack to support reading rectangles from a string + std::string rect_string; + + child_nodep->getAttributeString("value", rect_string); + std::istringstream istream(rect_string); + S32 left, bottom, width, height; + + istream >> left >> bottom >> width >> height; + + LLRect rect; + rect.setOriginAndSize(left, bottom, width, height); + + control->set(rect.getValue()); + validitems++; + } + break; + case TYPE_COL4: + { + LLColor4 color; + + child_nodep->getAttributeColor4("value", color); + control->set(color.getValue()); + validitems++; + } + break; + case TYPE_COL3: + { + LLVector3 color; + + child_nodep->getAttributeVector3("value", color); + control->set(LLColor3(color.mV).getValue()); + validitems++; + } + break; + + default: + break; + + } + + child_nodep = rootp->getNextChild(); + } + + return validitems; } U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only) { - LLSD settings; - int num_saved = 0; - for (ctrl_name_table_t::iterator iter = mNameTable.begin(); - iter != mNameTable.end(); iter++) - { - LLControlVariable* control = iter->second; - if (!control) - { - LL_WARNS("Settings") << "Tried to save invalid control: " << iter->first << LL_ENDL; - } - else if( control->shouldSave(nondefault_only) ) - { - settings[iter->first]["Type"] = typeEnumToString(control->type()); - settings[iter->first]["Comment"] = control->getComment(); - settings[iter->first]["Value"] = control->getSaveValue(); - ++num_saved; - } - } - llofstream file; - file.open(filename.c_str()); - if (file.is_open()) - { - LLSDSerialize::toPrettyXML(settings, file); - file.close(); - LL_INFOS("Settings") << "Saved to " << filename << LL_ENDL; - } - else - { + LLSD settings; + int num_saved = 0; + for (ctrl_name_table_t::iterator iter = mNameTable.begin(); + iter != mNameTable.end(); iter++) + { + LLControlVariable* control = iter->second; + if (!control) + { + LL_WARNS("Settings") << "Tried to save invalid control: " << iter->first << LL_ENDL; + } + else if( control->shouldSave(nondefault_only) ) + { + settings[iter->first]["Type"] = typeEnumToString(control->type()); + settings[iter->first]["Comment"] = control->getComment(); + settings[iter->first]["Value"] = control->getSaveValue(); + ++num_saved; + } + } + llofstream file; + file.open(filename.c_str()); + if (file.is_open()) + { + LLSDSerialize::toPrettyXML(settings, file); + file.close(); + LL_INFOS("Settings") << "Saved to " << filename << LL_ENDL; + } + else + { // This is a warning because sometime we want to use settings files which can't be written... - LL_WARNS("Settings") << "Unable to open settings file: " << filename << LL_ENDL; - return 0; - } - return num_saved; + LL_WARNS("Settings") << "Unable to open settings file: " << filename << LL_ENDL; + return 0; + } + return num_saved; } U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_values, bool save_values) { - LLSD settings; - llifstream infile; - infile.open(filename.c_str()); - if(!infile.is_open()) - { - LL_WARNS("Settings") << "Cannot find file " << filename << " to load." << LL_ENDL; - return 0; - } - - 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, 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; - std::string const & name = itr->first; - LLSD const & control_map = itr->second; - - if(control_map.has("Persist")) - { - 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: - if(control_map.has("HideFromEditor")) - { - hidefromsettingseditor = control_map["HideFromEditor"].asInteger(); - } - else - { - hidefromsettingseditor = false; - } - - // If the control exists just set the value from the input file. - LLControlVariable* existing_control = getControl(name); - if(existing_control) - { - // set_default_values is true when we're loading the initial, - // immutable files from app_settings, e.g. settings.xml. - if(set_default_values) - { - // Override all previously set properties of this control. - // ... except for type. The types must match. - eControlType new_type = typeStringToEnum(control_map["Type"].asString()); - if(existing_control->isType(new_type)) - { - existing_control->setDefaultValue(control_map["Value"]); - existing_control->setPersist(persist); - existing_control->setHiddenFromSettingsEditor(hidefromsettingseditor); - existing_control->setComment(control_map["Comment"].asString()); - } - else - { - LL_ERRS() << "Mismatched type of control variable '" - << name << "' found while loading '" - << filename << "'." << LL_ENDL; - } - } - else if(existing_control->isPersisted()) - { - // save_values is specifically false for (e.g.) - // SessionSettingsFile and UserSessionSettingsFile -- in other - // words, for a file that's supposed to be transient. - existing_control->setValue(control_map["Value"], save_values); - } - // *NOTE: If not persisted and not setting defaults, - // the value should not get loaded. - } - else - { - // We've never seen this control before. Either we're loading up - // the initial set of default settings files (set_default_values) - // -- or we're loading user settings last saved by a viewer that - // supports a superset of the variables we know. - // CHOP-962: if we're loading an unrecognized user setting, make - // sure we save it later. If you try an experimental viewer, tweak - // a new setting, briefly revert to an old viewer, then return to - // the new one, we don't want the old viewer to discard the - // setting you changed. - if (! set_default_values) - { - // Using PERSIST_ALWAYS insists that saveToFile() (which calls - // LLControlVariable::shouldSave()) must save this control - // variable regardless of its value. We can safely set this - // LLControlVariable persistent because the 'persistent' flag - // is not itself persisted! - persist = LLControlVariable::PERSIST_ALWAYS; - // We want to mention unrecognized user settings variables - // (e.g. from a newer version of the viewer) in the log. But - // we also arrive here for Boolean variables generated by - // the notifications subsystem when the user checks "Don't - // show me this again." These aren't declared in settings.xml; - // they're actually named for the notification they suppress. - // We don't want to mention those. Apologies, this is a bit of - // a hack: we happen to know that user settings go into an - // LLControlGroup whose name is "Global". - if (getKey() == "Global") - { - LL_INFOS("LLControlGroup") << "preserving unrecognized " << getKey() - << " settings variable " << name << LL_ENDL; - } - } - - declareControl(name, - typeStringToEnum(control_map["Type"].asString()), - control_map["Value"], - control_map["Comment"].asString(), - persist, - hidefromsettingseditor - ); - } - - ++validitems; - } - - LL_DEBUGS("Settings") << "Loaded " << validitems << " settings from " << filename << LL_ENDL; - return validitems; + LLSD settings; + llifstream infile; + infile.open(filename.c_str()); + if(!infile.is_open()) + { + LL_WARNS("Settings") << "Cannot find file " << filename << " to load." << LL_ENDL; + return 0; + } + + 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, 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; + std::string const & name = itr->first; + LLSD const & control_map = itr->second; + + if(control_map.has("Persist")) + { + 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: + if(control_map.has("HideFromEditor")) + { + hidefromsettingseditor = control_map["HideFromEditor"].asInteger(); + } + else + { + hidefromsettingseditor = false; + } + + // If the control exists just set the value from the input file. + LLControlVariable* existing_control = getControl(name); + if(existing_control) + { + // set_default_values is true when we're loading the initial, + // immutable files from app_settings, e.g. settings.xml. + if(set_default_values) + { + // Override all previously set properties of this control. + // ... except for type. The types must match. + eControlType new_type = typeStringToEnum(control_map["Type"].asString()); + if(existing_control->isType(new_type)) + { + existing_control->setDefaultValue(control_map["Value"]); + existing_control->setPersist(persist); + existing_control->setHiddenFromSettingsEditor(hidefromsettingseditor); + existing_control->setComment(control_map["Comment"].asString()); + } + else + { + LL_ERRS() << "Mismatched type of control variable '" + << name << "' found while loading '" + << filename << "'." << LL_ENDL; + } + } + else if(existing_control->isPersisted()) + { + // save_values is specifically false for (e.g.) + // SessionSettingsFile and UserSessionSettingsFile -- in other + // words, for a file that's supposed to be transient. + existing_control->setValue(control_map["Value"], save_values); + } + // *NOTE: If not persisted and not setting defaults, + // the value should not get loaded. + } + else + { + // We've never seen this control before. Either we're loading up + // the initial set of default settings files (set_default_values) + // -- or we're loading user settings last saved by a viewer that + // supports a superset of the variables we know. + // CHOP-962: if we're loading an unrecognized user setting, make + // sure we save it later. If you try an experimental viewer, tweak + // a new setting, briefly revert to an old viewer, then return to + // the new one, we don't want the old viewer to discard the + // setting you changed. + if (! set_default_values) + { + // Using PERSIST_ALWAYS insists that saveToFile() (which calls + // LLControlVariable::shouldSave()) must save this control + // variable regardless of its value. We can safely set this + // LLControlVariable persistent because the 'persistent' flag + // is not itself persisted! + persist = LLControlVariable::PERSIST_ALWAYS; + // We want to mention unrecognized user settings variables + // (e.g. from a newer version of the viewer) in the log. But + // we also arrive here for Boolean variables generated by + // the notifications subsystem when the user checks "Don't + // show me this again." These aren't declared in settings.xml; + // they're actually named for the notification they suppress. + // We don't want to mention those. Apologies, this is a bit of + // a hack: we happen to know that user settings go into an + // LLControlGroup whose name is "Global". + if (getKey() == "Global") + { + LL_INFOS("LLControlGroup") << "preserving unrecognized " << getKey() + << " settings variable " << name << LL_ENDL; + } + } + + declareControl(name, + typeStringToEnum(control_map["Type"].asString()), + control_map["Value"], + control_map["Comment"].asString(), + persist, + hidefromsettingseditor + ); + } + + ++validitems; + } + + LL_DEBUGS("Settings") << "Loaded " << validitems << " settings from " << filename << LL_ENDL; + return validitems; } void LLControlGroup::resetToDefaults() { - ctrl_name_table_t::iterator control_iter; - for (control_iter = mNameTable.begin(); - control_iter != mNameTable.end(); - ++control_iter) - { - LLControlVariable* control = (*control_iter).second; - control->resetToDefault(); - } + ctrl_name_table_t::iterator control_iter; + for (control_iter = mNameTable.begin(); + control_iter != mNameTable.end(); + ++control_iter) + { + LLControlVariable* control = (*control_iter).second; + control->resetToDefault(); + } } void LLControlGroup::applyToAll(ApplyFunctor* func) { - for (ctrl_name_table_t::iterator iter = mNameTable.begin(); - iter != mNameTable.end(); iter++) - { - func->apply(iter->first, iter->second); - } + for (ctrl_name_table_t::iterator iter = mNameTable.begin(); + iter != mNameTable.end(); iter++) + { + func->apply(iter->first, iter->second); + } } //============================================================================ @@ -1146,335 +1146,335 @@ void LLControlGroup::applyToAll(ApplyFunctor* func) #ifdef TEST_HARNESS void main() { - F32_CONTROL foo, getfoo; + F32_CONTROL foo, getfoo; + + S32_CONTROL bar, getbar; - S32_CONTROL bar, getbar; - - BOOL_CONTROL baz; + BOOL_CONTROL baz; - U32 count = gGlobals.loadFromFile("controls.ini"); - LL_INFOS("Settings") << "Loaded " << count << " controls" << LL_ENDL; + U32 count = gGlobals.loadFromFile("controls.ini"); + LL_INFOS("Settings") << "Loaded " << count << " controls" << LL_ENDL; - // test insertion - foo = new LLControlVariable("gFoo", 5.f, 1.f, 20.f); - gGlobals.addEntry("gFoo", foo); + // test insertion + foo = new LLControlVariable("gFoo", 5.f, 1.f, 20.f); + gGlobals.addEntry("gFoo", foo); - bar = new LLControlVariable("gBar", 10, 2, 22); - gGlobals.addEntry("gBar", bar); + bar = new LLControlVariable("gBar", 10, 2, 22); + gGlobals.addEntry("gBar", bar); - baz = new LLControlVariable("gBaz", FALSE); - gGlobals.addEntry("gBaz", baz); + baz = new LLControlVariable("gBaz", FALSE); + gGlobals.addEntry("gBaz", baz); - // test retrieval - getfoo = (LLControlVariable*) gGlobals.resolveName("gFoo"); - getfoo->dump(); + // test retrieval + getfoo = (LLControlVariable*) gGlobals.resolveName("gFoo"); + getfoo->dump(); - getbar = (S32_CONTROL) gGlobals.resolveName("gBar"); - getbar->dump(); + getbar = (S32_CONTROL) gGlobals.resolveName("gBar"); + getbar->dump(); - // change data - getfoo->set(10.f); - getfoo->dump(); + // change data + getfoo->set(10.f); + getfoo->dump(); - // Failure modes + // Failure modes - // ...min > max - // badfoo = new LLControlVariable("gFoo2", 100.f, 20.f, 5.f); + // ...min > max + // badfoo = new LLControlVariable("gFoo2", 100.f, 20.f, 5.f); - // ...initial > max - // badbar = new LLControlVariable("gBar2", 10, 20, 100000); + // ...initial > max + // badbar = new LLControlVariable("gBar2", 10, 20, 100000); - // ...misspelled name - // getfoo = (F32_CONTROL) gGlobals.resolveName("fooMisspelled"); - // getfoo->dump(); + // ...misspelled name + // getfoo = (F32_CONTROL) gGlobals.resolveName("fooMisspelled"); + // getfoo->dump(); - // ...invalid data type - getfoo = (F32_CONTROL) gGlobals.resolveName("gFoo"); - getfoo->set(TRUE); - getfoo->dump(); + // ...invalid data type + getfoo = (F32_CONTROL) gGlobals.resolveName("gFoo"); + getfoo->set(TRUE); + getfoo->dump(); - // ...out of range data - // getfoo->set(100000000.f); - // getfoo->dump(); + // ...out of range data + // getfoo->set(100000000.f); + // getfoo->dump(); - // Clean Up - delete foo; - delete bar; - delete baz; + // Clean Up + delete foo; + delete bar; + delete baz; } #endif -template <> eControlType get_control_type() -{ - return TYPE_U32; +template <> eControlType get_control_type() +{ + return TYPE_U32; } -template <> eControlType get_control_type() -{ - return TYPE_S32; +template <> eControlType get_control_type() +{ + return TYPE_S32; } -template <> eControlType get_control_type() -{ - return TYPE_F32; +template <> eControlType get_control_type() +{ + return TYPE_F32; } -template <> eControlType get_control_type () -{ - return TYPE_BOOLEAN; +template <> eControlType get_control_type () +{ + return TYPE_BOOLEAN; } /* // Yay BOOL, its really an S32. -template <> eControlType get_control_type () -{ - return TYPE_BOOLEAN; +template <> eControlType get_control_type () +{ + return TYPE_BOOLEAN; } */ -template <> eControlType get_control_type() -{ - return TYPE_STRING; +template <> eControlType get_control_type() +{ + return TYPE_STRING; } -template <> eControlType get_control_type() -{ - return TYPE_VEC3; +template <> eControlType get_control_type() +{ + return TYPE_VEC3; } -template <> eControlType get_control_type() -{ - return TYPE_VEC3D; +template <> eControlType get_control_type() +{ + return TYPE_VEC3D; } template <> eControlType get_control_type() { - return TYPE_QUAT; + return TYPE_QUAT; } -template <> eControlType get_control_type() -{ - return TYPE_RECT; +template <> eControlType get_control_type() +{ + return TYPE_RECT; } -template <> eControlType get_control_type() -{ - return TYPE_COL4; +template <> eControlType get_control_type() +{ + return TYPE_COL4; } -template <> eControlType get_control_type() -{ - return TYPE_COL3; +template <> eControlType get_control_type() +{ + return TYPE_COL3; } -template <> eControlType get_control_type() -{ - return TYPE_LLSD; +template <> eControlType get_control_type() +{ + return TYPE_LLSD; } -template <> LLSD convert_to_llsd(const U32& in) -{ - return (LLSD::Integer)in; +template <> LLSD convert_to_llsd(const U32& in) +{ + return (LLSD::Integer)in; } -template <> LLSD convert_to_llsd(const LLVector3& in) -{ - return in.getValue(); +template <> LLSD convert_to_llsd(const LLVector3& in) +{ + return in.getValue(); } -template <> LLSD convert_to_llsd(const LLVector3d& in) -{ - return in.getValue(); +template <> LLSD convert_to_llsd(const LLVector3d& in) +{ + return in.getValue(); } template <> LLSD convert_to_llsd(const LLQuaternion& in) { - return in.getValue(); + return in.getValue(); } -template <> LLSD convert_to_llsd(const LLRect& in) -{ - return in.getValue(); +template <> LLSD convert_to_llsd(const LLRect& in) +{ + return in.getValue(); } -template <> LLSD convert_to_llsd(const LLColor4& in) -{ - return in.getValue(); +template <> LLSD convert_to_llsd(const LLColor4& in) +{ + return in.getValue(); } -template <> LLSD convert_to_llsd(const LLColor3& in) -{ - return in.getValue(); +template <> LLSD convert_to_llsd(const LLColor3& in) +{ + return in.getValue(); } -template <> LLSD convert_to_llsd(const LLColor4U& in) -{ - return in.getValue(); +template <> LLSD convert_to_llsd(const LLColor4U& in) +{ + return in.getValue(); } template<> bool convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) { - if (type == TYPE_BOOLEAN) - return sd.asBoolean(); - else - { - CONTROL_ERRS << "Invalid BOOL value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return FALSE; - } + if (type == TYPE_BOOLEAN) + return sd.asBoolean(); + else + { + CONTROL_ERRS << "Invalid BOOL value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return FALSE; + } } template<> S32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) { - if (type == TYPE_S32) - return sd.asInteger(); - else - { - CONTROL_ERRS << "Invalid S32 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return 0; - } + if (type == TYPE_S32) + return sd.asInteger(); + else + { + CONTROL_ERRS << "Invalid S32 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return 0; + } } template<> U32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) { - if (type == TYPE_U32) - return sd.asInteger(); - else - { - CONTROL_ERRS << "Invalid U32 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return 0; - } + if (type == TYPE_U32) + return sd.asInteger(); + else + { + CONTROL_ERRS << "Invalid U32 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return 0; + } } template<> F32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) { - if (type == TYPE_F32) - return (F32) sd.asReal(); - else - { - CONTROL_ERRS << "Invalid F32 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return 0.0f; - } + if (type == TYPE_F32) + return (F32) sd.asReal(); + else + { + CONTROL_ERRS << "Invalid F32 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return 0.0f; + } } template<> std::string convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) { - if (type == TYPE_STRING) - return sd.asString(); - else - { - CONTROL_ERRS << "Invalid string value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return LLStringUtil::null; - } + if (type == TYPE_STRING) + return sd.asString(); + else + { + CONTROL_ERRS << "Invalid string value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return LLStringUtil::null; + } } template<> LLWString convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) { - return utf8str_to_wstring(convert_from_llsd(sd, type, control_name)); + return utf8str_to_wstring(convert_from_llsd(sd, type, control_name)); } template<> LLVector3 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) { - if (type == TYPE_VEC3) - return (LLVector3)sd; - else - { - CONTROL_ERRS << "Invalid LLVector3 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return LLVector3::zero; - } + if (type == TYPE_VEC3) + return (LLVector3)sd; + else + { + CONTROL_ERRS << "Invalid LLVector3 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return LLVector3::zero; + } } template<> LLVector3d convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) { - if (type == TYPE_VEC3D) - return (LLVector3d)sd; - else - { - CONTROL_ERRS << "Invalid LLVector3d value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return LLVector3d::zero; - } + if (type == TYPE_VEC3D) + return (LLVector3d)sd; + else + { + CONTROL_ERRS << "Invalid LLVector3d value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return LLVector3d::zero; + } } template<> LLQuaternion convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) { - if (type == TYPE_QUAT) - return (LLQuaternion)sd; - else - { - CONTROL_ERRS << "Invalid LLQuaternion value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return LLQuaternion(); - } + if (type == TYPE_QUAT) + return (LLQuaternion)sd; + else + { + CONTROL_ERRS << "Invalid LLQuaternion value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return LLQuaternion(); + } } template<> LLRect convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) { - if (type == TYPE_RECT) - return LLRect(sd); - else - { - CONTROL_ERRS << "Invalid rect value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return LLRect::null; - } + if (type == TYPE_RECT) + return LLRect(sd); + else + { + CONTROL_ERRS << "Invalid rect value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return LLRect::null; + } } template<> LLColor4 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) { - if (type == TYPE_COL4) - { - LLColor4 color(sd); - if (color.mV[VRED] < 0.f || color.mV[VRED] > 1.f) - { - LL_WARNS("Settings") << "Color " << control_name << " red value out of range: " << color << LL_ENDL; - } - else if (color.mV[VGREEN] < 0.f || color.mV[VGREEN] > 1.f) - { - LL_WARNS("Settings") << "Color " << control_name << " green value out of range: " << color << LL_ENDL; - } - else if (color.mV[VBLUE] < 0.f || color.mV[VBLUE] > 1.f) - { - LL_WARNS("Settings") << "Color " << control_name << " blue value out of range: " << color << LL_ENDL; - } - else if (color.mV[VALPHA] < 0.f || color.mV[VALPHA] > 1.f) - { - LL_WARNS("Settings") << "Color " << control_name << " alpha value out of range: " << color << LL_ENDL; - } - - return LLColor4(sd); - } - else - { - CONTROL_ERRS << "Control " << control_name << " not a color" << LL_ENDL; - return LLColor4::white; - } + if (type == TYPE_COL4) + { + LLColor4 color(sd); + if (color.mV[VRED] < 0.f || color.mV[VRED] > 1.f) + { + LL_WARNS("Settings") << "Color " << control_name << " red value out of range: " << color << LL_ENDL; + } + else if (color.mV[VGREEN] < 0.f || color.mV[VGREEN] > 1.f) + { + LL_WARNS("Settings") << "Color " << control_name << " green value out of range: " << color << LL_ENDL; + } + else if (color.mV[VBLUE] < 0.f || color.mV[VBLUE] > 1.f) + { + LL_WARNS("Settings") << "Color " << control_name << " blue value out of range: " << color << LL_ENDL; + } + else if (color.mV[VALPHA] < 0.f || color.mV[VALPHA] > 1.f) + { + LL_WARNS("Settings") << "Color " << control_name << " alpha value out of range: " << color << LL_ENDL; + } + + return LLColor4(sd); + } + else + { + CONTROL_ERRS << "Control " << control_name << " not a color" << LL_ENDL; + return LLColor4::white; + } } template<> LLColor3 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) { - if (type == TYPE_COL3) - return sd; - else - { - CONTROL_ERRS << "Invalid LLColor3 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return LLColor3::white; - } + if (type == TYPE_COL3) + return sd; + else + { + CONTROL_ERRS << "Invalid LLColor3 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return LLColor3::white; + } } template<> LLSD convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) { - return sd; + return sd; } @@ -1502,21 +1502,21 @@ static LLCachedControl test_BrowserHomePage("BrowserHomePage", "hah void test_cached_control() { #define TEST_LLCC(T, V) if((T)mySetting_##T != V) LL_ERRS() << "Fail "#T << LL_ENDL - TEST_LLCC(U32, 666); - TEST_LLCC(S32, (S32)-666); - TEST_LLCC(F32, (F32)-666.666); - TEST_LLCC(bool, true); - TEST_LLCC(BOOL, FALSE); - if((std::string)mySetting_string != "Default String Value") LL_ERRS() << "Fail string" << LL_ENDL; - TEST_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f)); - TEST_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f)); - TEST_LLCC(LLRect, LLRect(0, 0, 100, 500)); - TEST_LLCC(LLColor4, LLColor4(0.0f, 0.5f, 1.0f)); - TEST_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f)); - TEST_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255)); -//There's no LLSD comparsion for LLCC yet. TEST_LLCC(LLSD, test_llsd); - - if((std::string)test_BrowserHomePage != "http://www.secondlife.com") LL_ERRS() << "Fail BrowserHomePage" << LL_ENDL; + TEST_LLCC(U32, 666); + TEST_LLCC(S32, (S32)-666); + TEST_LLCC(F32, (F32)-666.666); + TEST_LLCC(bool, true); + TEST_LLCC(BOOL, FALSE); + if((std::string)mySetting_string != "Default String Value") LL_ERRS() << "Fail string" << LL_ENDL; + TEST_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f)); + TEST_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f)); + TEST_LLCC(LLRect, LLRect(0, 0, 100, 500)); + TEST_LLCC(LLColor4, LLColor4(0.0f, 0.5f, 1.0f)); + TEST_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f)); + TEST_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255)); +//There's no LLSD comparsion for LLCC yet. TEST_LLCC(LLSD, test_llsd); + + if((std::string)test_BrowserHomePage != "http://www.secondlife.com") LL_ERRS() << "Fail BrowserHomePage" << LL_ENDL; } #endif // TEST_CACHED_CONTROL diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 5a8d688892..62b0c12770 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -1,25 +1,25 @@ -/** +/** * @file llcontrol.h * @brief A mechanism for storing "control state" for a program * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -48,13 +48,13 @@ #include #if LL_WINDOWS - #pragma warning (push) - #pragma warning (disable : 4263) // boost::signals2::expired_slot::what() has const mismatch - #pragma warning (disable : 4264) + #pragma warning (push) + #pragma warning (disable : 4263) // boost::signals2::expired_slot::what() has const mismatch + #pragma warning (disable : 4264) #endif #include #if LL_WINDOWS - #pragma warning (pop) + #pragma warning (pop) #endif #if LL_WINDOWS @@ -72,241 +72,241 @@ class LLColor3; // if this is changed, also modify mTypeString in llcontrol.h typedef enum e_control_type { - TYPE_U32 = 0, - TYPE_S32, - TYPE_F32, - TYPE_BOOLEAN, - TYPE_STRING, - TYPE_VEC3, - TYPE_VEC3D, - TYPE_QUAT, - TYPE_RECT, - TYPE_COL4, - TYPE_COL3, - TYPE_LLSD, - TYPE_COUNT + TYPE_U32 = 0, + TYPE_S32, + TYPE_F32, + TYPE_BOOLEAN, + TYPE_STRING, + TYPE_VEC3, + TYPE_VEC3D, + TYPE_QUAT, + TYPE_RECT, + TYPE_COL4, + TYPE_COL3, + TYPE_LLSD, + TYPE_COUNT } eControlType; class LLControlVariable : public LLRefCount { - LOG_CLASS(LLControlVariable); + LOG_CLASS(LLControlVariable); + + friend class LLControlGroup; - friend class LLControlGroup; - public: - typedef boost::signals2::signal validate_signal_t; - typedef boost::signals2::signal commit_signal_t; + typedef boost::signals2::signal validate_signal_t; + typedef boost::signals2::signal commit_signal_t; - enum ePersist - { - PERSIST_NO, // don't save this var - PERSIST_NONDFT, // save this var if differs from default - PERSIST_ALWAYS // save this var even if has default value - }; + enum ePersist + { + PERSIST_NO, // don't save this var + PERSIST_NONDFT, // save this var if differs from default + PERSIST_ALWAYS // save this var even if has default value + }; private: - std::string mName; - std::string mComment; - eControlType mType; - ePersist mPersist; - bool mHideFromSettingsEditor; - std::vector mValues; - - commit_signal_t mCommitSignal; - validate_signal_t mValidateSignal; - + std::string mName; + std::string mComment; + eControlType mType; + ePersist mPersist; + bool mHideFromSettingsEditor; + std::vector mValues; + + commit_signal_t mCommitSignal; + validate_signal_t mValidateSignal; + public: - LLControlVariable(const std::string& name, eControlType type, - LLSD initial, const std::string& comment, - ePersist persist = PERSIST_NONDFT, bool hidefromsettingseditor = false); - - virtual ~LLControlVariable(); - - const std::string& getName() const { return mName; } - const std::string& getComment() const { return mComment; } - - eControlType type() { return mType; } - bool isType(eControlType tp) { return tp == mType; } - - void resetToDefault(bool fire_signal = false); - - commit_signal_t* getSignal() { return &mCommitSignal; } // shorthand for commit signal - commit_signal_t* getCommitSignal() { return &mCommitSignal; } - validate_signal_t* getValidateSignal() { return &mValidateSignal; } - - bool isDefault() { return (mValues.size() == 1); } - bool shouldSave(bool nondefault_only); - bool isPersisted() { return mPersist != PERSIST_NO; } - bool isHiddenFromSettingsEditor() { return mHideFromSettingsEditor; } - LLSD get() const { return getValue(); } - LLSD getValue() const { return mValues.back(); } - LLSD getDefault() const { return mValues.front(); } - LLSD getSaveValue() const; - - void set(const LLSD& val, bool saved_value = true) { setValue(val, saved_value); } - void setValue(const LLSD& value, bool saved_value = TRUE); - void setDefaultValue(const LLSD& value); - void setPersist(ePersist); - void setHiddenFromSettingsEditor(bool hide); - void setComment(const std::string& comment); + LLControlVariable(const std::string& name, eControlType type, + LLSD initial, const std::string& comment, + ePersist persist = PERSIST_NONDFT, bool hidefromsettingseditor = false); + + virtual ~LLControlVariable(); + + const std::string& getName() const { return mName; } + const std::string& getComment() const { return mComment; } + + eControlType type() { return mType; } + bool isType(eControlType tp) { return tp == mType; } + + void resetToDefault(bool fire_signal = false); + + commit_signal_t* getSignal() { return &mCommitSignal; } // shorthand for commit signal + commit_signal_t* getCommitSignal() { return &mCommitSignal; } + validate_signal_t* getValidateSignal() { return &mValidateSignal; } + + bool isDefault() { return (mValues.size() == 1); } + bool shouldSave(bool nondefault_only); + bool isPersisted() { return mPersist != PERSIST_NO; } + bool isHiddenFromSettingsEditor() { return mHideFromSettingsEditor; } + LLSD get() const { return getValue(); } + LLSD getValue() const { return mValues.back(); } + LLSD getDefault() const { return mValues.front(); } + LLSD getSaveValue() const; + + void set(const LLSD& val, bool saved_value = true) { setValue(val, saved_value); } + void setValue(const LLSD& value, bool saved_value = TRUE); + void setDefaultValue(const LLSD& value); + void setPersist(ePersist); + void setHiddenFromSettingsEditor(bool hide); + void setComment(const std::string& comment); private: - void firePropertyChanged(const LLSD &pPreviousValue) - { - mCommitSignal(this, mValues.back(), pPreviousValue); - } - LLSD getComparableValue(const LLSD& value); - bool llsd_compare(const LLSD& a, const LLSD & b); + void firePropertyChanged(const LLSD &pPreviousValue) + { + mCommitSignal(this, mValues.back(), pPreviousValue); + } + LLSD getComparableValue(const LLSD& value); + bool llsd_compare(const LLSD& a, const LLSD & b); }; typedef LLPointer LLControlVariablePtr; //! Helper functions for converting between static types and LLControl values -template +template eControlType get_control_type() { - LL_WARNS() << "Usupported control type: " << typeid(T).name() << "." << LL_ENDL; - return TYPE_COUNT; + LL_WARNS() << "Usupported control type: " << typeid(T).name() << "." << LL_ENDL; + return TYPE_COUNT; } -template +template LLSD convert_to_llsd(const T& in) { - // default implementation - return LLSD(in); + // default implementation + return LLSD(in); } template T convert_from_llsd(const LLSD& sd, eControlType type, const std::string& control_name) { - // needs specialization - return T(sd); + // needs specialization + return T(sd); } //const U32 STRING_CACHE_SIZE = 10000; class LLControlGroup : public LLInstanceTracker { - LOG_CLASS(LLControlGroup); + LOG_CLASS(LLControlGroup); protected: - typedef std::map ctrl_name_table_t; - ctrl_name_table_t mNameTable; - static const std::string mTypeString[TYPE_COUNT]; + typedef std::map ctrl_name_table_t; + ctrl_name_table_t mNameTable; + static const std::string mTypeString[TYPE_COUNT]; public: - static eControlType typeStringToEnum(const std::string& typestr); - static std::string typeEnumToString(eControlType typeenum); - - LLControlGroup(const std::string& name); - ~LLControlGroup(); - void cleanup(); - - LLControlVariablePtr getControl(const std::string& name); - - struct ApplyFunctor - { - virtual ~ApplyFunctor() {}; - virtual void apply(const std::string& name, LLControlVariable* control) = 0; - }; - void applyToAll(ApplyFunctor* func); - - LLControlVariable* declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, BOOL hidefromsettingseditor = FALSE); - LLControlVariable* declareU32(const std::string& name, U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareS32(const std::string& name, S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareF32(const std::string& name, F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareQuat(const std::string& name, const LLQuaternion &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - - std::string getString(const std::string& name); - std::string getText(const std::string& name); - BOOL getBOOL(const std::string& name); - S32 getS32(const std::string& name); - F32 getF32(const std::string& name); - U32 getU32(const std::string& name); - - LLWString getWString(const std::string& name); - LLVector3 getVector3(const std::string& name); - LLVector3d getVector3d(const std::string& name); - LLRect getRect(const std::string& name); - LLSD getLLSD(const std::string& name); - LLQuaternion getQuaternion(const std::string& name); - - LLColor4 getColor(const std::string& name); - LLColor4 getColor4(const std::string& name); - LLColor3 getColor3(const std::string& name); - - LLSD asLLSD(bool diffs_only); - - // generic getter - template T get(const std::string& name) - { + static eControlType typeStringToEnum(const std::string& typestr); + static std::string typeEnumToString(eControlType typeenum); + + LLControlGroup(const std::string& name); + ~LLControlGroup(); + void cleanup(); + + LLControlVariablePtr getControl(const std::string& name); + + struct ApplyFunctor + { + virtual ~ApplyFunctor() {}; + virtual void apply(const std::string& name, LLControlVariable* control) = 0; + }; + void applyToAll(ApplyFunctor* func); + + LLControlVariable* declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, BOOL hidefromsettingseditor = FALSE); + LLControlVariable* declareU32(const std::string& name, U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareS32(const std::string& name, S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareF32(const std::string& name, F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareQuat(const std::string& name, const LLQuaternion &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + + std::string getString(const std::string& name); + std::string getText(const std::string& name); + BOOL getBOOL(const std::string& name); + S32 getS32(const std::string& name); + F32 getF32(const std::string& name); + U32 getU32(const std::string& name); + + LLWString getWString(const std::string& name); + LLVector3 getVector3(const std::string& name); + LLVector3d getVector3d(const std::string& name); + LLRect getRect(const std::string& name); + LLSD getLLSD(const std::string& name); + LLQuaternion getQuaternion(const std::string& name); + + LLColor4 getColor(const std::string& name); + LLColor4 getColor4(const std::string& name); + LLColor3 getColor3(const std::string& name); + + LLSD asLLSD(bool diffs_only); + + // generic getter + template T get(const std::string& name) + { LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; - LLControlVariable* control = getControl(name); - LLSD value; - eControlType type = TYPE_COUNT; - - if (control) - { - value = control->get(); - type = control->type(); - } - else - { - LL_WARNS() << "Control " << name << " not found." << LL_ENDL; - return T(); - } - return convert_from_llsd(value, type, name); - } - - void setBOOL(const std::string& name, BOOL val); - void setS32(const std::string& name, S32 val); - void setF32(const std::string& name, F32 val); - void setU32(const std::string& name, U32 val); - void setString(const std::string& name, const std::string& val); - void setVector3(const std::string& name, const LLVector3 &val); - void setVector3d(const std::string& name, const LLVector3d &val); - void setQuaternion(const std::string& name, const LLQuaternion &val); - void setRect(const std::string& name, const LLRect &val); - void setColor4(const std::string& name, const LLColor4 &val); - void setLLSD(const std::string& name, const LLSD& val); - - // type agnostic setter that takes LLSD - void setUntypedValue(const std::string& name, const LLSD& val, bool saved_value = true); - - // generic setter - template void set(const std::string& name, const T& val) - { - LLControlVariable* control = getControl(name); - - if (control && control->isType(get_control_type())) - { - control->set(convert_to_llsd(val)); - } - else - { - LL_WARNS() << "Invalid control " << name << LL_ENDL; - } - } - - BOOL controlExists(const std::string& name); - - // 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, 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(); - void incrCount(const std::string& name); - - bool mSettingsProfile; + LLControlVariable* control = getControl(name); + LLSD value; + eControlType type = TYPE_COUNT; + + if (control) + { + value = control->get(); + type = control->type(); + } + else + { + LL_WARNS() << "Control " << name << " not found." << LL_ENDL; + return T(); + } + return convert_from_llsd(value, type, name); + } + + void setBOOL(const std::string& name, BOOL val); + void setS32(const std::string& name, S32 val); + void setF32(const std::string& name, F32 val); + void setU32(const std::string& name, U32 val); + void setString(const std::string& name, const std::string& val); + void setVector3(const std::string& name, const LLVector3 &val); + void setVector3d(const std::string& name, const LLVector3d &val); + void setQuaternion(const std::string& name, const LLQuaternion &val); + void setRect(const std::string& name, const LLRect &val); + void setColor4(const std::string& name, const LLColor4 &val); + void setLLSD(const std::string& name, const LLSD& val); + + // type agnostic setter that takes LLSD + void setUntypedValue(const std::string& name, const LLSD& val, bool saved_value = true); + + // generic setter + template void set(const std::string& name, const T& val) + { + LLControlVariable* control = getControl(name); + + if (control && control->isType(get_control_type())) + { + control->set(convert_to_llsd(val)); + } + else + { + LL_WARNS() << "Invalid control " << name << LL_ENDL; + } + } + + BOOL controlExists(const std::string& name); + + // 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, 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(); + void incrCount(const std::string& name); + + bool mSettingsProfile; }; @@ -319,124 +319,124 @@ template class LLControlCache : public LLRefCount, public LLInstanceTracker, std::string> { public: - // This constructor will declare a control if it doesn't exist in the contol group - LLControlCache(LLControlGroup& group, - const std::string& name, - const T& default_value, - const std::string& comment) - : LLInstanceTracker, std::string >(name) - { - if(!group.controlExists(name)) - { - if(!declareTypedControl(group, name, default_value, comment)) - { - LL_ERRS() << "The control could not be created!!!" << LL_ENDL; - } - } - - bindToControl(group, name); - } - - LLControlCache(LLControlGroup& group, - const std::string& name) - : LLInstanceTracker, std::string >(name) - { - if(!group.controlExists(name)) - { - LL_ERRS() << "Control named " << name << "not found." << LL_ENDL; - } - - bindToControl(group, name); - } - - ~LLControlCache() - { - } - - const T& getValue() const { return mCachedValue; } - + // This constructor will declare a control if it doesn't exist in the contol group + LLControlCache(LLControlGroup& group, + const std::string& name, + const T& default_value, + const std::string& comment) + : LLInstanceTracker, std::string >(name) + { + if(!group.controlExists(name)) + { + if(!declareTypedControl(group, name, default_value, comment)) + { + LL_ERRS() << "The control could not be created!!!" << LL_ENDL; + } + } + + bindToControl(group, name); + } + + LLControlCache(LLControlGroup& group, + const std::string& name) + : LLInstanceTracker, std::string >(name) + { + if(!group.controlExists(name)) + { + LL_ERRS() << "Control named " << name << "not found." << LL_ENDL; + } + + bindToControl(group, name); + } + + ~LLControlCache() + { + } + + const T& getValue() const { return mCachedValue; } + private: - void bindToControl(LLControlGroup& group, const std::string& name) - { - LLControlVariablePtr controlp = group.getControl(name); - mType = controlp->type(); - mCachedValue = convert_from_llsd(controlp->get(), mType, name); - - // Add a listener to the controls signal... - // NOTE: All listeners connected to 0 group, for guaranty that variable handlers (gSavedSettings) call last - mConnection = controlp->getSignal()->connect(0, - boost::bind(&LLControlCache::handleValueChange, this, _2) - ); - mType = controlp->type(); - } - bool declareTypedControl(LLControlGroup& group, - const std::string& name, - const T& default_value, - const std::string& comment) - { - LLSD init_value; - eControlType type = get_control_type(); - init_value = convert_to_llsd(default_value); - if(type < TYPE_COUNT) - { - group.declareControl(name, type, init_value, comment, LLControlVariable::PERSIST_NO); - return true; - } - return false; - } - - bool handleValueChange(const LLSD& newvalue) - { - mCachedValue = convert_from_llsd(newvalue, mType, ""); - return true; - } + void bindToControl(LLControlGroup& group, const std::string& name) + { + LLControlVariablePtr controlp = group.getControl(name); + mType = controlp->type(); + mCachedValue = convert_from_llsd(controlp->get(), mType, name); + + // Add a listener to the controls signal... + // NOTE: All listeners connected to 0 group, for guaranty that variable handlers (gSavedSettings) call last + mConnection = controlp->getSignal()->connect(0, + boost::bind(&LLControlCache::handleValueChange, this, _2) + ); + mType = controlp->type(); + } + bool declareTypedControl(LLControlGroup& group, + const std::string& name, + const T& default_value, + const std::string& comment) + { + LLSD init_value; + eControlType type = get_control_type(); + init_value = convert_to_llsd(default_value); + if(type < TYPE_COUNT) + { + group.declareControl(name, type, init_value, comment, LLControlVariable::PERSIST_NO); + return true; + } + return false; + } + + bool handleValueChange(const LLSD& newvalue) + { + mCachedValue = convert_from_llsd(newvalue, mType, ""); + return true; + } private: - T mCachedValue; - eControlType mType; - boost::signals2::scoped_connection mConnection; + T mCachedValue; + eControlType mType; + boost::signals2::scoped_connection mConnection; }; template class LLCachedControl { public: - LLCachedControl(LLControlGroup& group, - const std::string& name, - const T& default_value, - const std::string& comment = "Declared In Code") - { - mCachedControlPtr = LLControlCache::getInstance(name).get(); - if (! mCachedControlPtr) - { - mCachedControlPtr = new LLControlCache(group, name, default_value, comment); - } - } - - LLCachedControl(LLControlGroup& group, - const std::string& name) - { - mCachedControlPtr = LLControlCache::getInstance(name).get(); - if (! mCachedControlPtr) - { - mCachedControlPtr = new LLControlCache(group, name); - } - } - - operator const T&() const { return mCachedControlPtr->getValue(); } - operator boost::function () const { return boost::function(*this); } - const T& operator()() { return mCachedControlPtr->getValue(); } + LLCachedControl(LLControlGroup& group, + const std::string& name, + const T& default_value, + const std::string& comment = "Declared In Code") + { + mCachedControlPtr = LLControlCache::getInstance(name).get(); + if (! mCachedControlPtr) + { + mCachedControlPtr = new LLControlCache(group, name, default_value, comment); + } + } + + LLCachedControl(LLControlGroup& group, + const std::string& name) + { + mCachedControlPtr = LLControlCache::getInstance(name).get(); + if (! mCachedControlPtr) + { + mCachedControlPtr = new LLControlCache(group, name); + } + } + + operator const T&() const { return mCachedControlPtr->getValue(); } + operator boost::function () const { return boost::function(*this); } + const T& operator()() { return mCachedControlPtr->getValue(); } private: - LLPointer > mCachedControlPtr; + LLPointer > mCachedControlPtr; }; template <> eControlType get_control_type(); template <> eControlType get_control_type(); template <> eControlType get_control_type(); -template <> eControlType get_control_type(); +template <> eControlType get_control_type(); // Yay BOOL, its really an S32. -//template <> eControlType get_control_type () +//template <> eControlType get_control_type () template <> eControlType get_control_type(); template <> eControlType get_control_type(); template <> eControlType get_control_type(); -- cgit v1.2.3 From 4fbb190453200c12169fdcc3e151df2fa73c0db4 Mon Sep 17 00:00:00 2001 From: Beq Janus Date: Fri, 17 May 2024 16:48:03 +0100 Subject: fix bad indentation and modernise (#1503) --- indra/llxml/llxmltree.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llxmltree.cpp b/indra/llxml/llxmltree.cpp index baf2e6a951..cd41aa6f2d 100644 --- a/indra/llxml/llxmltree.cpp +++ b/indra/llxml/llxmltree.cpp @@ -108,14 +108,17 @@ LLXmlTreeNode::LLXmlTreeNode( const std::string& name, LLXmlTreeNode* parent, LL LLXmlTreeNode::~LLXmlTreeNode() { - attribute_map_t::iterator iter; - for (iter=mAttributes.begin(); iter != mAttributes.end(); iter++) - delete iter->second; - for(LLXmlTreeNode* node : mChildren) - { - delete node; - } - mChildren.clear(); + for (auto& attr : mAttributes) + { + delete attr.second; + } + mAttributes.clear(); + + for (auto& child : mChildren) + { + delete child; + } + mChildren.clear(); } void LLXmlTreeNode::dump( const std::string& prefix ) -- cgit v1.2.3 From e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 22 May 2024 21:25:21 +0200 Subject: Fix line endlings --- indra/llxml/llcontrol.cpp | 3016 ++++++++-------- indra/llxml/llcontrol.h | 948 ++--- indra/llxml/llxmlnode.cpp | 6536 +++++++++++++++++----------------- indra/llxml/llxmlnode.h | 670 ++-- indra/llxml/llxmlparser.cpp | 832 ++--- indra/llxml/llxmlparser.h | 266 +- indra/llxml/llxmltree.cpp | 1388 ++++---- indra/llxml/llxmltree.h | 468 +-- indra/llxml/tests/llcontrol_test.cpp | 308 +- 9 files changed, 7216 insertions(+), 7216 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index beeca105bc..82e07e03c9 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -1,1508 +1,1508 @@ -/** - * @file llcontrol.cpp - * @brief Holds global state for viewer. - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include -#include -#include - -#include "llcontrol.h" - -#include "llstl.h" - -#include "llstring.h" -#include "v3math.h" -#include "v3dmath.h" -#include "v4coloru.h" -#include "v4color.h" -#include "v3color.h" -#include "llquaternion.h" -#include "llrect.h" -#include "llxmltree.h" -#include "llsdserialize.h" -#include "llfile.h" -#include "lltimer.h" -#include "lldir.h" - -#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG -#define CONTROL_ERRS LL_ERRS("ControlErrors") -#else -#define CONTROL_ERRS LL_WARNS("ControlErrors") -#endif - - -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); - -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); - -template <> LLSD convert_to_llsd(const U32& in); -template <> LLSD convert_to_llsd(const LLVector3& in); -template <> LLSD convert_to_llsd(const LLVector3d& in); -template <> LLSD convert_to_llsd(const LLRect& in); -template <> LLSD convert_to_llsd(const LLColor4& in); -template <> LLSD convert_to_llsd(const LLColor3& in); -template <> LLSD convert_to_llsd(const LLColor4U& in); - -template <> bool convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template <> S32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template <> U32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template <> F32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template <> std::string convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template <> LLWString convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template <> LLVector3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template <> LLVector3d convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template <> LLRect convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template <> LLColor4 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template <> LLColor4U convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template <> LLColor3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template <> LLSD convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); - -//this defines the current version of the settings file -const S32 CURRENT_VERSION = 101; - -// If you define the environment variable LL_SETTINGS_PROFILE to any value this will activate -// the gSavedSettings profiling code. This code tracks the calls to get a saved (debug) setting. -// When the viewer exits the results are written to the log directory to the file specified -// by SETTINGS_PROFILE below. Only settings with an average access rate >= 2/second are output. -typedef std::pair settings_pair_t; -typedef std::vector settings_vec_t; -LLSD getCount; -settings_vec_t getCount_v; -F64 start_time = 0; -std::string SETTINGS_PROFILE = "settings_profile.log"; - -bool LLControlVariable::llsd_compare(const LLSD& a, const LLSD & b) -{ - bool result = false; - switch (mType) - { - case TYPE_U32: - case TYPE_S32: - result = a.asInteger() == b.asInteger(); - break; - case TYPE_BOOLEAN: - result = a.asBoolean() == b.asBoolean(); - break; - case TYPE_F32: - result = a.asReal() == b.asReal(); - break; - case TYPE_VEC3: - case TYPE_VEC3D: - result = LLVector3d(a) == LLVector3d(b); - break; - case TYPE_QUAT: - result = LLQuaternion(a) == LLQuaternion(b); - break; - case TYPE_RECT: - result = LLRect(a) == LLRect(b); - break; - case TYPE_COL4: - result = LLColor4(a) == LLColor4(b); - break; - case TYPE_COL3: - result = LLColor3(a) == LLColor3(b); - break; - case TYPE_STRING: - result = a.asString() == b.asString(); - break; - default: - break; - } - - return result; -} - -LLControlVariable::LLControlVariable(const std::string& name, eControlType type, - LLSD initial, const std::string& comment, - ePersist persist, bool hidefromsettingseditor) - : mName(name), - mComment(comment), - mType(type), - mPersist(persist), - mHideFromSettingsEditor(hidefromsettingseditor) -{ - if ((persist != PERSIST_NO) && mComment.empty()) - { - LL_ERRS() << "Must supply a comment for control " << mName << LL_ENDL; - } - //Push back versus setValue'ing here, since we don't want to call a signal yet - mValues.push_back(initial); -} - - - -LLControlVariable::~LLControlVariable() -{ -} - -LLSD LLControlVariable::getComparableValue(const LLSD& value) -{ - // *FIX:MEP - The following is needed to make the LLSD::ImplString - // work with boolean controls... - LLSD storable_value; - if(TYPE_BOOLEAN == type() && value.isString()) - { - bool temp; - if(LLStringUtil::convertToBOOL(value.asString(), temp)) - { - storable_value = temp; - } - else - { - storable_value = false; - } - } - else if (TYPE_LLSD == type() && value.isString()) - { - LLPointer parser = new LLSDNotationParser; - LLSD result; - std::stringstream value_stream(value.asString()); - if (parser->parse(value_stream, result, LLSDSerialize::SIZE_UNLIMITED) != LLSDParser::PARSE_FAILURE) - { - storable_value = result; - } - else - { - storable_value = value; - } - } - else - { - storable_value = value; - } - - return storable_value; -} - -void LLControlVariable::setValue(const LLSD& new_value, bool saved_value) -{ - if (!mValidateSignal(this, new_value)) - { - // can not set new value, exit - return; - } - - LLSD storable_value = getComparableValue(new_value); - LLSD original_value = getValue(); - bool value_changed = !llsd_compare(original_value, storable_value); - if(saved_value) - { - // If we're going to save this value, return to default but don't fire - resetToDefault(false); - if (!llsd_compare(mValues.back(), storable_value)) - { - mValues.push_back(storable_value); - } - } - else - { - // This is an unsaved value. Its needs to reside at - // mValues[2] (or greater). It must not affect - // the result of getSaveValue() - if (!llsd_compare(mValues.back(), storable_value)) - { - while(mValues.size() > 2) - { - // Remove any unsaved values. - mValues.pop_back(); - } - - if(mValues.size() < 2) - { - // Add the default to the 'save' value. - mValues.push_back(mValues[0]); - } - - // Add the 'un-save' value. - mValues.push_back(storable_value); - } - } - - if(value_changed) - { - firePropertyChanged(original_value); - } -} - -void LLControlVariable::setDefaultValue(const LLSD& value) -{ - // Set the control variables value and make it - // the default value. If the active value is changed, - // send the signal. - // *NOTE: Default values are not saved, only read. - - LLSD comparable_value = getComparableValue(value); - LLSD original_value = getValue(); - bool value_changed = !llsd_compare(original_value, comparable_value); - resetToDefault(false); - mValues[0] = comparable_value; - if (value_changed) - { - firePropertyChanged(original_value); - } -} - -void LLControlVariable::setPersist(ePersist state) -{ - mPersist = state; -} - -void LLControlVariable::setHiddenFromSettingsEditor(bool hide) -{ - mHideFromSettingsEditor = hide; -} - -void LLControlVariable::setComment(const std::string& comment) -{ - mComment = comment; -} - -void LLControlVariable::resetToDefault(bool fire_signal) -{ - //The first setting is always the default - //Pop to it and fire off the listener - LLSD originalValue = mValues.back(); - - while(mValues.size() > 1) - { - mValues.pop_back(); - } - - if(fire_signal) - { - firePropertyChanged(originalValue); - } -} - -bool LLControlVariable::shouldSave(bool nondefault_only) -{ - // This method is used to decide whether we should save a given - // variable. Two of the three values of mPersist are easy. - if (mPersist == PERSIST_NO) - return false; - - if (mPersist == PERSIST_ALWAYS) - return true; - - // PERSIST_NONDFT - // If caller doesn't need us to filter, just save. - if (! nondefault_only) - return true; - - // PERSIST_NONDFT: caller only wants us to save this variable if its value - // differs from default. - if (isDefault()) // never been altered - return false; - - // We've set at least one other value: compare it to default. Save only if - // they differ. - return ! llsd_compare(getSaveValue(), getDefault()); -} - -LLSD LLControlVariable::getSaveValue() const -{ - //The first level of the stack is default - //We assume that the second level is user preferences that should be saved - if(mValues.size() > 1) return mValues[1]; - return mValues[0]; -} - -LLPointer LLControlGroup::getControl(std::string_view name) -{ - if (mSettingsProfile) - { - incrCount(name); - } - - ctrl_name_table_t::iterator iter = mNameTable.find(name.data()); - return iter == mNameTable.end() ? LLPointer() : iter->second; -} - - -//////////////////////////////////////////////////////////////////////////// - -// Must match the type definition in llcontrol.h -const std::string LLControlGroup::mTypeString[TYPE_COUNT] = { "U32" - ,"S32" - ,"F32" - ,"Boolean" - ,"String" - ,"Vector3" - ,"Vector3D" - ,"Quaternion" - ,"Rect" - ,"Color4" - ,"Color3" - ,"LLSD" - }; - -LLControlGroup::LLControlGroup(const std::string& name) -: LLInstanceTracker(name), - mSettingsProfile(false) -{ - - if (NULL != getenv("LL_SETTINGS_PROFILE")) - { - mSettingsProfile = true; - } -} - -LLControlGroup::~LLControlGroup() -{ - cleanup(); -} - -static bool compareRoutine(settings_pair_t lhs, settings_pair_t rhs) -{ - return lhs.second > rhs.second; -}; - -void LLControlGroup::cleanup() -{ - if(mSettingsProfile && getCount.size() != 0) - { - std::string file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, SETTINGS_PROFILE); - LLFILE* out = LLFile::fopen(file, "w"); /* Flawfinder: ignore */ - if(!out) - { - LL_WARNS("SettingsProfile") << "Error opening " << SETTINGS_PROFILE << LL_ENDL; - } - else - { - F64 end_time = LLTimer::getTotalSeconds(); - U32 total_seconds = (U32)(end_time - start_time); - - std::string msg = llformat("Runtime (seconds): %d\n\n No. accesses Avg. accesses/sec Name\n", total_seconds); - std::ostringstream data_msg; - - data_msg << msg; - size_t data_size = data_msg.str().size(); - if (fwrite(data_msg.str().c_str(), 1, data_size, out) != data_size) - { - LL_WARNS("SettingsProfile") << "Failed to write settings profile header" << LL_ENDL; - } - - for (LLSD::map_const_iterator iter = getCount.beginMap(); iter != getCount.endMap(); ++iter) - { - getCount_v.push_back(settings_pair_t(iter->first, iter->second.asInteger())); - } - sort(getCount_v.begin(), getCount_v.end(), compareRoutine); - - for (settings_vec_t::iterator iter = getCount_v.begin(); iter != getCount_v.end(); ++iter) - { - U32 access_rate = 0; - if (total_seconds != 0) - { - access_rate = iter->second / total_seconds; - } - if (access_rate >= 2) - { - std::ostringstream data_msg; - msg = llformat("%13d %7d %s", iter->second, access_rate, iter->first.c_str()); - data_msg << msg << "\n"; - size_t data_size = data_msg.str().size(); - if (fwrite(data_msg.str().c_str(), 1, data_size, out) != data_size) - { - LL_WARNS("SettingsProfile") << "Failed to write settings profile" << LL_ENDL; - } - } - } - getCount = LLSD::emptyMap(); - fclose(out); - } - } - - mNameTable.clear(); -} - -eControlType LLControlGroup::typeStringToEnum(const std::string& typestr) -{ - for(int i = 0; i < (int)TYPE_COUNT; ++i) - { - if(mTypeString[i] == typestr) return (eControlType)i; - } - return (eControlType)-1; -} - -std::string LLControlGroup::typeEnumToString(eControlType typeenum) -{ - return mTypeString[typeenum]; -} - -LLControlVariable* LLControlGroup::declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, bool hidefromsettingseditor) -{ - LLControlVariable* existing_control = getControl(name); - if (existing_control) - { - if ((persist != LLControlVariable::PERSIST_NO) && existing_control->isType(type)) - { - if (!existing_control->llsd_compare(existing_control->getDefault(), initial_val)) - { - // Sometimes we need to declare a control *after* it has been loaded from a settings file. - LLSD cur_value = existing_control->getValue(); // get the current value - existing_control->setDefaultValue(initial_val); // set the default to the declared value - existing_control->setValue(cur_value); // now set to the loaded value - } - } - else - { - LL_WARNS("Settings") << "Control named " << name << " already exists, ignoring new declaration." << LL_ENDL; - } - return existing_control; - } - - // if not, create the control and add it to the name table - LLControlVariable* control = new LLControlVariable(name, type, initial_val, comment, persist, hidefromsettingseditor); - mNameTable[name] = control; - return control; -} - -LLControlVariable* LLControlGroup::declareU32(const std::string& name, const U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist) -{ - return declareControl(name, TYPE_U32, (LLSD::Integer) initial_val, comment, persist); -} - -LLControlVariable* LLControlGroup::declareS32(const std::string& name, const S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist) -{ - return declareControl(name, TYPE_S32, initial_val, comment, persist); -} - -LLControlVariable* LLControlGroup::declareF32(const std::string& name, const F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist) -{ - return declareControl(name, TYPE_F32, initial_val, comment, persist); -} - -LLControlVariable* LLControlGroup::declareBOOL(const std::string& name, const bool initial_val, const std::string& comment, LLControlVariable::ePersist persist) -{ - return declareControl(name, TYPE_BOOLEAN, initial_val, comment, persist); -} - -LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string& initial_val, const std::string& comment, LLControlVariable::ePersist persist) -{ - return declareControl(name, TYPE_STRING, initial_val, comment, persist); -} - -LLControlVariable* LLControlGroup::declareVec3(const std::string& name, const LLVector3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist) -{ - return declareControl(name, TYPE_VEC3, initial_val.getValue(), comment, persist); -} - -LLControlVariable* LLControlGroup::declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist) -{ - return declareControl(name, TYPE_VEC3D, initial_val.getValue(), comment, persist); -} - -LLControlVariable* LLControlGroup::declareQuat(const std::string& name, const LLQuaternion &initial_val, const std::string& comment, LLControlVariable::ePersist persist) -{ - return declareControl(name, TYPE_QUAT, initial_val.getValue(), comment, persist); -} - -LLControlVariable* LLControlGroup::declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist) -{ - return declareControl(name, TYPE_RECT, initial_val.getValue(), comment, persist); -} - -LLControlVariable* LLControlGroup::declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist ) -{ - return declareControl(name, TYPE_COL4, initial_val.getValue(), comment, persist); -} - -LLControlVariable* LLControlGroup::declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist ) -{ - return declareControl(name, TYPE_COL3, initial_val.getValue(), comment, persist); -} - -LLControlVariable* LLControlGroup::declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, LLControlVariable::ePersist persist ) -{ - return declareControl(name, TYPE_LLSD, initial_val, comment, persist); -} - -void LLControlGroup::incrCount(std::string_view name) -{ - if (0.0 == start_time) - { - start_time = LLTimer::getTotalSeconds(); - } - getCount[name.data()] = getCount[name.data()].asInteger() + 1; -} - -bool LLControlGroup::getBOOL(std::string_view name) -{ - return get(name); -} - -S32 LLControlGroup::getS32(std::string_view name) -{ - return get(name); -} - -U32 LLControlGroup::getU32(std::string_view name) -{ - return get(name); -} - -F32 LLControlGroup::getF32(std::string_view name) -{ - return get(name); -} - -std::string LLControlGroup::getString(std::string_view name) -{ - return get(name); -} - -LLWString LLControlGroup::getWString(std::string_view name) -{ - return get(name); -} - -std::string LLControlGroup::getText(std::string_view name) -{ - std::string utf8_string = getString(name); - LLStringUtil::replaceChar(utf8_string, '^', '\n'); - LLStringUtil::replaceChar(utf8_string, '%', ' '); - return (utf8_string); -} - -LLVector3 LLControlGroup::getVector3(std::string_view name) -{ - return get(name); -} - -LLVector3d LLControlGroup::getVector3d(std::string_view name) -{ - return get(name); -} - -LLQuaternion LLControlGroup::getQuaternion(std::string_view name) -{ - return get(name); -} - -LLRect LLControlGroup::getRect(std::string_view name) -{ - return get(name); -} - - -LLColor4 LLControlGroup::getColor(std::string_view name) -{ - return get(name); -} - -LLColor4 LLControlGroup::getColor4(std::string_view name) -{ - return get(name); -} - -LLColor3 LLControlGroup::getColor3(std::string_view name) -{ - return get(name); -} - -LLSD LLControlGroup::getLLSD(std::string_view name) -{ - return get(name); -} - -LLSD LLControlGroup::asLLSD(bool diffs_only) -{ - // Dump all stored values as LLSD - LLSD result = LLSD::emptyArray(); - for (ctrl_name_table_t::iterator iter = mNameTable.begin(); - iter != mNameTable.end(); iter++) - { - LLControlVariable *control = iter->second; - if (!control || control->isType(TYPE_STRING) || (diffs_only && control->isDefault())) - { - continue; - } - const std::string& name = iter->first; - result[name] = getLLSD(name); - } - return result; -} - -bool LLControlGroup::controlExists(const std::string& name) -{ - ctrl_name_table_t::iterator iter = mNameTable.find(name); - return iter != mNameTable.end(); -} - - -//------------------------------------------------------------------- -// Set functions -//------------------------------------------------------------------- - -void LLControlGroup::setBOOL(std::string_view name, bool val) -{ - set(name, val); -} - - -void LLControlGroup::setS32(std::string_view name, S32 val) -{ - set(name, val); -} - - -void LLControlGroup::setF32(std::string_view name, F32 val) -{ - set(name, val); -} - - -void LLControlGroup::setU32(std::string_view name, U32 val) -{ - set(name, val); -} - - -void LLControlGroup::setString(std::string_view name, const std::string &val) -{ - set(name, val); -} - - -void LLControlGroup::setVector3(std::string_view name, const LLVector3 &val) -{ - set(name, val); -} - -void LLControlGroup::setVector3d(std::string_view name, const LLVector3d &val) -{ - set(name, val); -} - -void LLControlGroup::setQuaternion(std::string_view name, const LLQuaternion &val) -{ - set(name, val); -} - -void LLControlGroup::setRect(std::string_view name, const LLRect &val) -{ - set(name, val); -} - -void LLControlGroup::setColor4(std::string_view name, const LLColor4 &val) -{ - set(name, val); -} - -void LLControlGroup::setLLSD(std::string_view name, const LLSD& val) -{ - set(name, val); -} - -void LLControlGroup::setUntypedValue(std::string_view name, const LLSD& val) -{ - if (name.empty()) - { - return; - } - - LLControlVariable* control = getControl(name); - - if (control) - { - control->setValue(val); - } - else - { - CONTROL_ERRS << "Invalid control " << name << LL_ENDL; - } -} - - -//--------------------------------------------------------------- -// Load and save -//--------------------------------------------------------------- - -// Returns number of controls loaded, so 0 if failure -U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, bool require_declaration, eControlType declare_as) -{ - std::string name; - - LLXmlTree xml_controls; - - if (!xml_controls.parseFile(filename)) - { - LL_WARNS("Settings") << "Unable to open control file " << filename << LL_ENDL; - return 0; - } - - LLXmlTreeNode* rootp = xml_controls.getRoot(); - if (!rootp || !rootp->hasAttribute("version")) - { - LL_WARNS("Settings") << "No valid settings header found in control file " << filename << LL_ENDL; - return 0; - } - - U32 validitems = 0; - S32 version; - - rootp->getAttributeS32("version", version); - - // Check file version - if (version != CURRENT_VERSION) - { - LL_INFOS("Settings") << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << LL_ENDL; - return 0; - } - - LLXmlTreeNode* child_nodep = rootp->getFirstChild(); - while(child_nodep) - { - name = child_nodep->getName(); - - bool declared = controlExists(name); - - if (require_declaration && !declared) - { - // Declaration required, but this name not declared. - // Complain about non-empty names. - if (!name.empty()) - { - //read in to end of line - LL_WARNS("Settings") << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << LL_ENDL; - } - child_nodep = rootp->getNextChild(); - continue; - } - - // Got an item. Load it up. - // If not declared, assume it's a string - if (!declared) - { - switch(declare_as) - { - case TYPE_COL4: - declareColor4(name, LLColor4::white, LLStringUtil::null, LLControlVariable::PERSIST_NO); - break; - case TYPE_STRING: - default: - declareString(name, LLStringUtil::null, LLStringUtil::null, LLControlVariable::PERSIST_NO); - break; - } - } - - // Control name has been declared in code. - LLControlVariable *control = getControl(name); - - llassert(control); - - switch(control->mType) - { - case TYPE_F32: - { - F32 initial = 0.f; - - child_nodep->getAttributeF32("value", initial); - - control->set(initial); - validitems++; - } - break; - case TYPE_S32: - { - S32 initial = 0; - - child_nodep->getAttributeS32("value", initial); - - control->set(initial); - validitems++; - } - break; - case TYPE_U32: - { - U32 initial = 0; - child_nodep->getAttributeU32("value", initial); - control->set((LLSD::Integer) initial); - validitems++; - } - break; - case TYPE_BOOLEAN: - { - bool initial = false; - - child_nodep->getAttributeBOOL("value", initial); - control->set(initial); - - validitems++; - } - break; - case TYPE_STRING: - { - std::string string; - child_nodep->getAttributeString("value", string); - control->set(string); - validitems++; - } - break; - case TYPE_VEC3: - { - LLVector3 vector; - - child_nodep->getAttributeVector3("value", vector); - control->set(vector.getValue()); - validitems++; - } - break; - case TYPE_VEC3D: - { - LLVector3d vector; - - child_nodep->getAttributeVector3d("value", vector); - - control->set(vector.getValue()); - validitems++; - } - break; - case TYPE_QUAT: - { - LLQuaternion quat; - - child_nodep->getAttributeQuat("value", quat); - - control->set(quat.getValue()); - validitems++; - } - break; - case TYPE_RECT: - { - //RN: hack to support reading rectangles from a string - std::string rect_string; - - child_nodep->getAttributeString("value", rect_string); - std::istringstream istream(rect_string); - S32 left, bottom, width, height; - - istream >> left >> bottom >> width >> height; - - LLRect rect; - rect.setOriginAndSize(left, bottom, width, height); - - control->set(rect.getValue()); - validitems++; - } - break; - case TYPE_COL4: - { - LLColor4 color; - - child_nodep->getAttributeColor4("value", color); - control->set(color.getValue()); - validitems++; - } - break; - case TYPE_COL3: - { - LLVector3 color; - - child_nodep->getAttributeVector3("value", color); - control->set(LLColor3(color.mV).getValue()); - validitems++; - } - break; - - default: - break; - - } - - child_nodep = rootp->getNextChild(); - } - - return validitems; -} - -U32 LLControlGroup::saveToFile(const std::string& filename, bool nondefault_only) -{ - LLSD settings; - int num_saved = 0; - for (ctrl_name_table_t::iterator iter = mNameTable.begin(); - iter != mNameTable.end(); iter++) - { - LLControlVariable* control = iter->second; - if (!control) - { - LL_WARNS("Settings") << "Tried to save invalid control: " << iter->first << LL_ENDL; - } - else if( control->shouldSave(nondefault_only) ) - { - settings[iter->first]["Type"] = typeEnumToString(control->type()); - settings[iter->first]["Comment"] = control->getComment(); - settings[iter->first]["Value"] = control->getSaveValue(); - ++num_saved; - } - } - llofstream file; - file.open(filename.c_str()); - if (file.is_open()) - { - LLSDSerialize::toPrettyXML(settings, file); - file.close(); - LL_INFOS("Settings") << "Saved to " << filename << LL_ENDL; - } - else - { - // This is a warning because sometime we want to use settings files which can't be written... - LL_WARNS("Settings") << "Unable to open settings file: " << filename << LL_ENDL; - return 0; - } - return num_saved; -} - -U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_values, bool save_values) -{ - LLSD settings; - llifstream infile; - infile.open(filename.c_str()); - if(!infile.is_open()) - { - LL_WARNS("Settings") << "Cannot find file " << filename << " to load." << LL_ENDL; - return 0; - } - - 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, 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; - std::string const & name = itr->first; - LLSD const & control_map = itr->second; - - if(control_map.has("Persist")) - { - 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: - if(control_map.has("HideFromEditor")) - { - hidefromsettingseditor = control_map["HideFromEditor"].asInteger(); - } - else - { - hidefromsettingseditor = false; - } - - // If the control exists just set the value from the input file. - LLControlVariable* existing_control = getControl(name); - if(existing_control) - { - // set_default_values is true when we're loading the initial, - // immutable files from app_settings, e.g. settings.xml. - if(set_default_values) - { - // Override all previously set properties of this control. - // ... except for type. The types must match. - eControlType new_type = typeStringToEnum(control_map["Type"].asString()); - if(existing_control->isType(new_type)) - { - existing_control->setDefaultValue(control_map["Value"]); - existing_control->setPersist(persist); - existing_control->setHiddenFromSettingsEditor(hidefromsettingseditor); - existing_control->setComment(control_map["Comment"].asString()); - } - else - { - LL_ERRS() << "Mismatched type of control variable '" - << name << "' found while loading '" - << filename << "'." << LL_ENDL; - } - } - else if(existing_control->isPersisted()) - { - // save_values is specifically false for (e.g.) - // SessionSettingsFile and UserSessionSettingsFile -- in other - // words, for a file that's supposed to be transient. - existing_control->setValue(control_map["Value"], save_values); - } - // *NOTE: If not persisted and not setting defaults, - // the value should not get loaded. - } - else - { - // We've never seen this control before. Either we're loading up - // the initial set of default settings files (set_default_values) - // -- or we're loading user settings last saved by a viewer that - // supports a superset of the variables we know. - // CHOP-962: if we're loading an unrecognized user setting, make - // sure we save it later. If you try an experimental viewer, tweak - // a new setting, briefly revert to an old viewer, then return to - // the new one, we don't want the old viewer to discard the - // setting you changed. - if (! set_default_values) - { - // Using PERSIST_ALWAYS insists that saveToFile() (which calls - // LLControlVariable::shouldSave()) must save this control - // variable regardless of its value. We can safely set this - // LLControlVariable persistent because the 'persistent' flag - // is not itself persisted! - persist = LLControlVariable::PERSIST_ALWAYS; - // We want to mention unrecognized user settings variables - // (e.g. from a newer version of the viewer) in the log. But - // we also arrive here for Boolean variables generated by - // the notifications subsystem when the user checks "Don't - // show me this again." These aren't declared in settings.xml; - // they're actually named for the notification they suppress. - // We don't want to mention those. Apologies, this is a bit of - // a hack: we happen to know that user settings go into an - // LLControlGroup whose name is "Global". - if (getKey() == "Global") - { - LL_INFOS("LLControlGroup") << "preserving unrecognized " << getKey() - << " settings variable " << name << LL_ENDL; - } - } - - declareControl(name, - typeStringToEnum(control_map["Type"].asString()), - control_map["Value"], - control_map["Comment"].asString(), - persist, - hidefromsettingseditor - ); - } - - ++validitems; - } - - LL_DEBUGS("Settings") << "Loaded " << validitems << " settings from " << filename << LL_ENDL; - return validitems; -} - -void LLControlGroup::resetToDefaults() -{ - ctrl_name_table_t::iterator control_iter; - for (control_iter = mNameTable.begin(); - control_iter != mNameTable.end(); - ++control_iter) - { - LLControlVariable* control = (*control_iter).second; - control->resetToDefault(); - } -} - -void LLControlGroup::applyToAll(ApplyFunctor* func) -{ - for (ctrl_name_table_t::iterator iter = mNameTable.begin(); - iter != mNameTable.end(); iter++) - { - func->apply(iter->first, iter->second); - } -} - -//============================================================================ - -#ifdef TEST_HARNESS -void main() -{ - F32_CONTROL foo, getfoo; - - S32_CONTROL bar, getbar; - - BOOL_CONTROL baz; - - U32 count = gGlobals.loadFromFile("controls.ini"); - LL_INFOS("Settings") << "Loaded " << count << " controls" << LL_ENDL; - - // test insertion - foo = new LLControlVariable("gFoo", 5.f, 1.f, 20.f); - gGlobals.addEntry("gFoo", foo); - - bar = new LLControlVariable("gBar", 10, 2, 22); - gGlobals.addEntry("gBar", bar); - - baz = new LLControlVariable("gBaz", false); - gGlobals.addEntry("gBaz", baz); - - // test retrieval - getfoo = (LLControlVariable*) gGlobals.resolveName("gFoo"); - getfoo->dump(); - - getbar = (S32_CONTROL) gGlobals.resolveName("gBar"); - getbar->dump(); - - // change data - getfoo->set(10.f); - getfoo->dump(); - - // Failure modes - - // ...min > max - // badfoo = new LLControlVariable("gFoo2", 100.f, 20.f, 5.f); - - // ...initial > max - // badbar = new LLControlVariable("gBar2", 10, 20, 100000); - - // ...misspelled name - // getfoo = (F32_CONTROL) gGlobals.resolveName("fooMisspelled"); - // getfoo->dump(); - - // ...invalid data type - getfoo = (F32_CONTROL) gGlobals.resolveName("gFoo"); - getfoo->set(true); - getfoo->dump(); - - // ...out of range data - // getfoo->set(100000000.f); - // getfoo->dump(); - - // Clean Up - delete foo; - delete bar; - delete baz; -} -#endif - - -template <> eControlType get_control_type() -{ - return TYPE_U32; -} - -template <> eControlType get_control_type() -{ - return TYPE_S32; -} - -template <> eControlType get_control_type() -{ - return TYPE_F32; -} - -template <> eControlType get_control_type () -{ - return TYPE_BOOLEAN; -} - -template <> eControlType get_control_type() -{ - return TYPE_STRING; -} - -template <> eControlType get_control_type() -{ - return TYPE_VEC3; -} - -template <> eControlType get_control_type() -{ - return TYPE_VEC3D; -} - -template <> eControlType get_control_type() -{ - return TYPE_QUAT; -} - -template <> eControlType get_control_type() -{ - return TYPE_RECT; -} - -template <> eControlType get_control_type() -{ - return TYPE_COL4; -} - -template <> eControlType get_control_type() -{ - return TYPE_COL3; -} - -template <> eControlType get_control_type() -{ - return TYPE_LLSD; -} - - -template <> LLSD convert_to_llsd(const U32& in) -{ - return (LLSD::Integer)in; -} - -template <> LLSD convert_to_llsd(const LLVector3& in) -{ - return in.getValue(); -} - -template <> LLSD convert_to_llsd(const LLVector3d& in) -{ - return in.getValue(); -} -template <> LLSD convert_to_llsd(const LLQuaternion& in) -{ - return in.getValue(); -} - -template <> LLSD convert_to_llsd(const LLRect& in) -{ - return in.getValue(); -} - -template <> LLSD convert_to_llsd(const LLColor4& in) -{ - return in.getValue(); -} - -template <> LLSD convert_to_llsd(const LLColor3& in) -{ - return in.getValue(); -} - -template <> LLSD convert_to_llsd(const LLColor4U& in) -{ - return in.getValue(); -} - - -template<> -bool convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) -{ - if (type == TYPE_BOOLEAN) - return sd.asBoolean(); - else - { - CONTROL_ERRS << "Invalid bool value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return false; - } -} - -template<> -S32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) -{ - if (type == TYPE_S32) - return sd.asInteger(); - else - { - CONTROL_ERRS << "Invalid S32 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return 0; - } -} - -template<> -U32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) -{ - if (type == TYPE_U32) - return sd.asInteger(); - else - { - CONTROL_ERRS << "Invalid U32 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return 0; - } -} - -template<> -F32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) -{ - if (type == TYPE_F32) - return (F32) sd.asReal(); - else - { - CONTROL_ERRS << "Invalid F32 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return 0.0f; - } -} - -template<> -std::string convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) -{ - if (type == TYPE_STRING) - return sd.asString(); - else - { - CONTROL_ERRS << "Invalid string value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return LLStringUtil::null; - } -} - -template<> -LLWString convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) -{ - return utf8str_to_wstring(convert_from_llsd(sd, type, control_name)); -} - -template<> -LLVector3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) -{ - if (type == TYPE_VEC3) - return (LLVector3)sd; - else - { - CONTROL_ERRS << "Invalid LLVector3 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return LLVector3::zero; - } -} - -template<> -LLVector3d convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) -{ - if (type == TYPE_VEC3D) - return (LLVector3d)sd; - else - { - CONTROL_ERRS << "Invalid LLVector3d value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return LLVector3d::zero; - } -} - -template<> -LLQuaternion convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) -{ - if (type == TYPE_QUAT) - return (LLQuaternion)sd; - else - { - CONTROL_ERRS << "Invalid LLQuaternion value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return LLQuaternion(); - } -} - -template<> -LLRect convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) -{ - if (type == TYPE_RECT) - return LLRect(sd); - else - { - CONTROL_ERRS << "Invalid rect value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return LLRect::null; - } -} - - -template<> -LLColor4 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) -{ - if (type == TYPE_COL4) - { - LLColor4 color(sd); - if (color.mV[VRED] < 0.f || color.mV[VRED] > 1.f) - { - LL_WARNS("Settings") << "Color " << control_name << " red value out of range: " << color << LL_ENDL; - } - else if (color.mV[VGREEN] < 0.f || color.mV[VGREEN] > 1.f) - { - LL_WARNS("Settings") << "Color " << control_name << " green value out of range: " << color << LL_ENDL; - } - else if (color.mV[VBLUE] < 0.f || color.mV[VBLUE] > 1.f) - { - LL_WARNS("Settings") << "Color " << control_name << " blue value out of range: " << color << LL_ENDL; - } - else if (color.mV[VALPHA] < 0.f || color.mV[VALPHA] > 1.f) - { - LL_WARNS("Settings") << "Color " << control_name << " alpha value out of range: " << color << LL_ENDL; - } - - return LLColor4(sd); - } - else - { - CONTROL_ERRS << "Control " << control_name << " not a color" << LL_ENDL; - return LLColor4::white; - } -} - -template<> -LLColor3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) -{ - if (type == TYPE_COL3) - return sd; - else - { - CONTROL_ERRS << "Invalid LLColor3 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; - return LLColor3::white; - } -} - -template<> -LLSD convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) -{ - return sd; -} - - -#if TEST_CACHED_CONTROL - -#define DECL_LLCC(T, V) static LLCachedControl mySetting_##T("TestCachedControl"#T, V) -DECL_LLCC(U32, (U32)666); -DECL_LLCC(S32, (S32)-666); -DECL_LLCC(F32, (F32)-666.666); -DECL_LLCC(bool, true); -static LLCachedControl mySetting_string("TestCachedControlstring", "Default String Value"); -DECL_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f)); -DECL_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f)); -DECL_LLCC(LLRect, LLRect(0, 0, 100, 500)); -DECL_LLCC(LLColor4, LLColor4(0.0f, 0.5f, 1.0f)); -DECL_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f)); -DECL_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255)); - -LLSD test_llsd = LLSD()["testing1"] = LLSD()["testing2"]; -DECL_LLCC(LLSD, test_llsd); - -void test_cached_control() -{ -#define TEST_LLCC(T, V) if((T)mySetting_##T != V) LL_ERRS() << "Fail "#T << LL_ENDL - TEST_LLCC(U32, 666); - TEST_LLCC(S32, (S32)-666); - TEST_LLCC(F32, (F32)-666.666); - TEST_LLCC(bool, true); - if((std::string)mySetting_string != "Default String Value") LL_ERRS() << "Fail string" << LL_ENDL; - TEST_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f)); - TEST_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f)); - TEST_LLCC(LLRect, LLRect(0, 0, 100, 500)); - TEST_LLCC(LLColor4, LLColor4(0.0f, 0.5f, 1.0f)); - TEST_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f)); - TEST_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255)); -//There's no LLSD comparsion for LLCC yet. TEST_LLCC(LLSD, test_llsd); -} -#endif // TEST_CACHED_CONTROL - +/** + * @file llcontrol.cpp + * @brief Holds global state for viewer. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include +#include +#include + +#include "llcontrol.h" + +#include "llstl.h" + +#include "llstring.h" +#include "v3math.h" +#include "v3dmath.h" +#include "v4coloru.h" +#include "v4color.h" +#include "v3color.h" +#include "llquaternion.h" +#include "llrect.h" +#include "llxmltree.h" +#include "llsdserialize.h" +#include "llfile.h" +#include "lltimer.h" +#include "lldir.h" + +#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG +#define CONTROL_ERRS LL_ERRS("ControlErrors") +#else +#define CONTROL_ERRS LL_WARNS("ControlErrors") +#endif + + +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); + +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); + +template <> LLSD convert_to_llsd(const U32& in); +template <> LLSD convert_to_llsd(const LLVector3& in); +template <> LLSD convert_to_llsd(const LLVector3d& in); +template <> LLSD convert_to_llsd(const LLRect& in); +template <> LLSD convert_to_llsd(const LLColor4& in); +template <> LLSD convert_to_llsd(const LLColor3& in); +template <> LLSD convert_to_llsd(const LLColor4U& in); + +template <> bool convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> S32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> U32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> F32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> std::string convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> LLWString convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> LLVector3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> LLVector3d convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> LLRect convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> LLColor4 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> LLColor4U convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> LLColor3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template <> LLSD convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); + +//this defines the current version of the settings file +const S32 CURRENT_VERSION = 101; + +// If you define the environment variable LL_SETTINGS_PROFILE to any value this will activate +// the gSavedSettings profiling code. This code tracks the calls to get a saved (debug) setting. +// When the viewer exits the results are written to the log directory to the file specified +// by SETTINGS_PROFILE below. Only settings with an average access rate >= 2/second are output. +typedef std::pair settings_pair_t; +typedef std::vector settings_vec_t; +LLSD getCount; +settings_vec_t getCount_v; +F64 start_time = 0; +std::string SETTINGS_PROFILE = "settings_profile.log"; + +bool LLControlVariable::llsd_compare(const LLSD& a, const LLSD & b) +{ + bool result = false; + switch (mType) + { + case TYPE_U32: + case TYPE_S32: + result = a.asInteger() == b.asInteger(); + break; + case TYPE_BOOLEAN: + result = a.asBoolean() == b.asBoolean(); + break; + case TYPE_F32: + result = a.asReal() == b.asReal(); + break; + case TYPE_VEC3: + case TYPE_VEC3D: + result = LLVector3d(a) == LLVector3d(b); + break; + case TYPE_QUAT: + result = LLQuaternion(a) == LLQuaternion(b); + break; + case TYPE_RECT: + result = LLRect(a) == LLRect(b); + break; + case TYPE_COL4: + result = LLColor4(a) == LLColor4(b); + break; + case TYPE_COL3: + result = LLColor3(a) == LLColor3(b); + break; + case TYPE_STRING: + result = a.asString() == b.asString(); + break; + default: + break; + } + + return result; +} + +LLControlVariable::LLControlVariable(const std::string& name, eControlType type, + LLSD initial, const std::string& comment, + ePersist persist, bool hidefromsettingseditor) + : mName(name), + mComment(comment), + mType(type), + mPersist(persist), + mHideFromSettingsEditor(hidefromsettingseditor) +{ + if ((persist != PERSIST_NO) && mComment.empty()) + { + LL_ERRS() << "Must supply a comment for control " << mName << LL_ENDL; + } + //Push back versus setValue'ing here, since we don't want to call a signal yet + mValues.push_back(initial); +} + + + +LLControlVariable::~LLControlVariable() +{ +} + +LLSD LLControlVariable::getComparableValue(const LLSD& value) +{ + // *FIX:MEP - The following is needed to make the LLSD::ImplString + // work with boolean controls... + LLSD storable_value; + if(TYPE_BOOLEAN == type() && value.isString()) + { + bool temp; + if(LLStringUtil::convertToBOOL(value.asString(), temp)) + { + storable_value = temp; + } + else + { + storable_value = false; + } + } + else if (TYPE_LLSD == type() && value.isString()) + { + LLPointer parser = new LLSDNotationParser; + LLSD result; + std::stringstream value_stream(value.asString()); + if (parser->parse(value_stream, result, LLSDSerialize::SIZE_UNLIMITED) != LLSDParser::PARSE_FAILURE) + { + storable_value = result; + } + else + { + storable_value = value; + } + } + else + { + storable_value = value; + } + + return storable_value; +} + +void LLControlVariable::setValue(const LLSD& new_value, bool saved_value) +{ + if (!mValidateSignal(this, new_value)) + { + // can not set new value, exit + return; + } + + LLSD storable_value = getComparableValue(new_value); + LLSD original_value = getValue(); + bool value_changed = !llsd_compare(original_value, storable_value); + if(saved_value) + { + // If we're going to save this value, return to default but don't fire + resetToDefault(false); + if (!llsd_compare(mValues.back(), storable_value)) + { + mValues.push_back(storable_value); + } + } + else + { + // This is an unsaved value. Its needs to reside at + // mValues[2] (or greater). It must not affect + // the result of getSaveValue() + if (!llsd_compare(mValues.back(), storable_value)) + { + while(mValues.size() > 2) + { + // Remove any unsaved values. + mValues.pop_back(); + } + + if(mValues.size() < 2) + { + // Add the default to the 'save' value. + mValues.push_back(mValues[0]); + } + + // Add the 'un-save' value. + mValues.push_back(storable_value); + } + } + + if(value_changed) + { + firePropertyChanged(original_value); + } +} + +void LLControlVariable::setDefaultValue(const LLSD& value) +{ + // Set the control variables value and make it + // the default value. If the active value is changed, + // send the signal. + // *NOTE: Default values are not saved, only read. + + LLSD comparable_value = getComparableValue(value); + LLSD original_value = getValue(); + bool value_changed = !llsd_compare(original_value, comparable_value); + resetToDefault(false); + mValues[0] = comparable_value; + if (value_changed) + { + firePropertyChanged(original_value); + } +} + +void LLControlVariable::setPersist(ePersist state) +{ + mPersist = state; +} + +void LLControlVariable::setHiddenFromSettingsEditor(bool hide) +{ + mHideFromSettingsEditor = hide; +} + +void LLControlVariable::setComment(const std::string& comment) +{ + mComment = comment; +} + +void LLControlVariable::resetToDefault(bool fire_signal) +{ + //The first setting is always the default + //Pop to it and fire off the listener + LLSD originalValue = mValues.back(); + + while(mValues.size() > 1) + { + mValues.pop_back(); + } + + if(fire_signal) + { + firePropertyChanged(originalValue); + } +} + +bool LLControlVariable::shouldSave(bool nondefault_only) +{ + // This method is used to decide whether we should save a given + // variable. Two of the three values of mPersist are easy. + if (mPersist == PERSIST_NO) + return false; + + if (mPersist == PERSIST_ALWAYS) + return true; + + // PERSIST_NONDFT + // If caller doesn't need us to filter, just save. + if (! nondefault_only) + return true; + + // PERSIST_NONDFT: caller only wants us to save this variable if its value + // differs from default. + if (isDefault()) // never been altered + return false; + + // We've set at least one other value: compare it to default. Save only if + // they differ. + return ! llsd_compare(getSaveValue(), getDefault()); +} + +LLSD LLControlVariable::getSaveValue() const +{ + //The first level of the stack is default + //We assume that the second level is user preferences that should be saved + if(mValues.size() > 1) return mValues[1]; + return mValues[0]; +} + +LLPointer LLControlGroup::getControl(std::string_view name) +{ + if (mSettingsProfile) + { + incrCount(name); + } + + ctrl_name_table_t::iterator iter = mNameTable.find(name.data()); + return iter == mNameTable.end() ? LLPointer() : iter->second; +} + + +//////////////////////////////////////////////////////////////////////////// + +// Must match the type definition in llcontrol.h +const std::string LLControlGroup::mTypeString[TYPE_COUNT] = { "U32" + ,"S32" + ,"F32" + ,"Boolean" + ,"String" + ,"Vector3" + ,"Vector3D" + ,"Quaternion" + ,"Rect" + ,"Color4" + ,"Color3" + ,"LLSD" + }; + +LLControlGroup::LLControlGroup(const std::string& name) +: LLInstanceTracker(name), + mSettingsProfile(false) +{ + + if (NULL != getenv("LL_SETTINGS_PROFILE")) + { + mSettingsProfile = true; + } +} + +LLControlGroup::~LLControlGroup() +{ + cleanup(); +} + +static bool compareRoutine(settings_pair_t lhs, settings_pair_t rhs) +{ + return lhs.second > rhs.second; +}; + +void LLControlGroup::cleanup() +{ + if(mSettingsProfile && getCount.size() != 0) + { + std::string file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, SETTINGS_PROFILE); + LLFILE* out = LLFile::fopen(file, "w"); /* Flawfinder: ignore */ + if(!out) + { + LL_WARNS("SettingsProfile") << "Error opening " << SETTINGS_PROFILE << LL_ENDL; + } + else + { + F64 end_time = LLTimer::getTotalSeconds(); + U32 total_seconds = (U32)(end_time - start_time); + + std::string msg = llformat("Runtime (seconds): %d\n\n No. accesses Avg. accesses/sec Name\n", total_seconds); + std::ostringstream data_msg; + + data_msg << msg; + size_t data_size = data_msg.str().size(); + if (fwrite(data_msg.str().c_str(), 1, data_size, out) != data_size) + { + LL_WARNS("SettingsProfile") << "Failed to write settings profile header" << LL_ENDL; + } + + for (LLSD::map_const_iterator iter = getCount.beginMap(); iter != getCount.endMap(); ++iter) + { + getCount_v.push_back(settings_pair_t(iter->first, iter->second.asInteger())); + } + sort(getCount_v.begin(), getCount_v.end(), compareRoutine); + + for (settings_vec_t::iterator iter = getCount_v.begin(); iter != getCount_v.end(); ++iter) + { + U32 access_rate = 0; + if (total_seconds != 0) + { + access_rate = iter->second / total_seconds; + } + if (access_rate >= 2) + { + std::ostringstream data_msg; + msg = llformat("%13d %7d %s", iter->second, access_rate, iter->first.c_str()); + data_msg << msg << "\n"; + size_t data_size = data_msg.str().size(); + if (fwrite(data_msg.str().c_str(), 1, data_size, out) != data_size) + { + LL_WARNS("SettingsProfile") << "Failed to write settings profile" << LL_ENDL; + } + } + } + getCount = LLSD::emptyMap(); + fclose(out); + } + } + + mNameTable.clear(); +} + +eControlType LLControlGroup::typeStringToEnum(const std::string& typestr) +{ + for(int i = 0; i < (int)TYPE_COUNT; ++i) + { + if(mTypeString[i] == typestr) return (eControlType)i; + } + return (eControlType)-1; +} + +std::string LLControlGroup::typeEnumToString(eControlType typeenum) +{ + return mTypeString[typeenum]; +} + +LLControlVariable* LLControlGroup::declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, bool hidefromsettingseditor) +{ + LLControlVariable* existing_control = getControl(name); + if (existing_control) + { + if ((persist != LLControlVariable::PERSIST_NO) && existing_control->isType(type)) + { + if (!existing_control->llsd_compare(existing_control->getDefault(), initial_val)) + { + // Sometimes we need to declare a control *after* it has been loaded from a settings file. + LLSD cur_value = existing_control->getValue(); // get the current value + existing_control->setDefaultValue(initial_val); // set the default to the declared value + existing_control->setValue(cur_value); // now set to the loaded value + } + } + else + { + LL_WARNS("Settings") << "Control named " << name << " already exists, ignoring new declaration." << LL_ENDL; + } + return existing_control; + } + + // if not, create the control and add it to the name table + LLControlVariable* control = new LLControlVariable(name, type, initial_val, comment, persist, hidefromsettingseditor); + mNameTable[name] = control; + return control; +} + +LLControlVariable* LLControlGroup::declareU32(const std::string& name, const U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist) +{ + return declareControl(name, TYPE_U32, (LLSD::Integer) initial_val, comment, persist); +} + +LLControlVariable* LLControlGroup::declareS32(const std::string& name, const S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist) +{ + return declareControl(name, TYPE_S32, initial_val, comment, persist); +} + +LLControlVariable* LLControlGroup::declareF32(const std::string& name, const F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist) +{ + return declareControl(name, TYPE_F32, initial_val, comment, persist); +} + +LLControlVariable* LLControlGroup::declareBOOL(const std::string& name, const bool initial_val, const std::string& comment, LLControlVariable::ePersist persist) +{ + return declareControl(name, TYPE_BOOLEAN, initial_val, comment, persist); +} + +LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string& initial_val, const std::string& comment, LLControlVariable::ePersist persist) +{ + return declareControl(name, TYPE_STRING, initial_val, comment, persist); +} + +LLControlVariable* LLControlGroup::declareVec3(const std::string& name, const LLVector3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist) +{ + return declareControl(name, TYPE_VEC3, initial_val.getValue(), comment, persist); +} + +LLControlVariable* LLControlGroup::declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist) +{ + return declareControl(name, TYPE_VEC3D, initial_val.getValue(), comment, persist); +} + +LLControlVariable* LLControlGroup::declareQuat(const std::string& name, const LLQuaternion &initial_val, const std::string& comment, LLControlVariable::ePersist persist) +{ + return declareControl(name, TYPE_QUAT, initial_val.getValue(), comment, persist); +} + +LLControlVariable* LLControlGroup::declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist) +{ + return declareControl(name, TYPE_RECT, initial_val.getValue(), comment, persist); +} + +LLControlVariable* LLControlGroup::declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist ) +{ + return declareControl(name, TYPE_COL4, initial_val.getValue(), comment, persist); +} + +LLControlVariable* LLControlGroup::declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist ) +{ + return declareControl(name, TYPE_COL3, initial_val.getValue(), comment, persist); +} + +LLControlVariable* LLControlGroup::declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, LLControlVariable::ePersist persist ) +{ + return declareControl(name, TYPE_LLSD, initial_val, comment, persist); +} + +void LLControlGroup::incrCount(std::string_view name) +{ + if (0.0 == start_time) + { + start_time = LLTimer::getTotalSeconds(); + } + getCount[name.data()] = getCount[name.data()].asInteger() + 1; +} + +bool LLControlGroup::getBOOL(std::string_view name) +{ + return get(name); +} + +S32 LLControlGroup::getS32(std::string_view name) +{ + return get(name); +} + +U32 LLControlGroup::getU32(std::string_view name) +{ + return get(name); +} + +F32 LLControlGroup::getF32(std::string_view name) +{ + return get(name); +} + +std::string LLControlGroup::getString(std::string_view name) +{ + return get(name); +} + +LLWString LLControlGroup::getWString(std::string_view name) +{ + return get(name); +} + +std::string LLControlGroup::getText(std::string_view name) +{ + std::string utf8_string = getString(name); + LLStringUtil::replaceChar(utf8_string, '^', '\n'); + LLStringUtil::replaceChar(utf8_string, '%', ' '); + return (utf8_string); +} + +LLVector3 LLControlGroup::getVector3(std::string_view name) +{ + return get(name); +} + +LLVector3d LLControlGroup::getVector3d(std::string_view name) +{ + return get(name); +} + +LLQuaternion LLControlGroup::getQuaternion(std::string_view name) +{ + return get(name); +} + +LLRect LLControlGroup::getRect(std::string_view name) +{ + return get(name); +} + + +LLColor4 LLControlGroup::getColor(std::string_view name) +{ + return get(name); +} + +LLColor4 LLControlGroup::getColor4(std::string_view name) +{ + return get(name); +} + +LLColor3 LLControlGroup::getColor3(std::string_view name) +{ + return get(name); +} + +LLSD LLControlGroup::getLLSD(std::string_view name) +{ + return get(name); +} + +LLSD LLControlGroup::asLLSD(bool diffs_only) +{ + // Dump all stored values as LLSD + LLSD result = LLSD::emptyArray(); + for (ctrl_name_table_t::iterator iter = mNameTable.begin(); + iter != mNameTable.end(); iter++) + { + LLControlVariable *control = iter->second; + if (!control || control->isType(TYPE_STRING) || (diffs_only && control->isDefault())) + { + continue; + } + const std::string& name = iter->first; + result[name] = getLLSD(name); + } + return result; +} + +bool LLControlGroup::controlExists(const std::string& name) +{ + ctrl_name_table_t::iterator iter = mNameTable.find(name); + return iter != mNameTable.end(); +} + + +//------------------------------------------------------------------- +// Set functions +//------------------------------------------------------------------- + +void LLControlGroup::setBOOL(std::string_view name, bool val) +{ + set(name, val); +} + + +void LLControlGroup::setS32(std::string_view name, S32 val) +{ + set(name, val); +} + + +void LLControlGroup::setF32(std::string_view name, F32 val) +{ + set(name, val); +} + + +void LLControlGroup::setU32(std::string_view name, U32 val) +{ + set(name, val); +} + + +void LLControlGroup::setString(std::string_view name, const std::string &val) +{ + set(name, val); +} + + +void LLControlGroup::setVector3(std::string_view name, const LLVector3 &val) +{ + set(name, val); +} + +void LLControlGroup::setVector3d(std::string_view name, const LLVector3d &val) +{ + set(name, val); +} + +void LLControlGroup::setQuaternion(std::string_view name, const LLQuaternion &val) +{ + set(name, val); +} + +void LLControlGroup::setRect(std::string_view name, const LLRect &val) +{ + set(name, val); +} + +void LLControlGroup::setColor4(std::string_view name, const LLColor4 &val) +{ + set(name, val); +} + +void LLControlGroup::setLLSD(std::string_view name, const LLSD& val) +{ + set(name, val); +} + +void LLControlGroup::setUntypedValue(std::string_view name, const LLSD& val) +{ + if (name.empty()) + { + return; + } + + LLControlVariable* control = getControl(name); + + if (control) + { + control->setValue(val); + } + else + { + CONTROL_ERRS << "Invalid control " << name << LL_ENDL; + } +} + + +//--------------------------------------------------------------- +// Load and save +//--------------------------------------------------------------- + +// Returns number of controls loaded, so 0 if failure +U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, bool require_declaration, eControlType declare_as) +{ + std::string name; + + LLXmlTree xml_controls; + + if (!xml_controls.parseFile(filename)) + { + LL_WARNS("Settings") << "Unable to open control file " << filename << LL_ENDL; + return 0; + } + + LLXmlTreeNode* rootp = xml_controls.getRoot(); + if (!rootp || !rootp->hasAttribute("version")) + { + LL_WARNS("Settings") << "No valid settings header found in control file " << filename << LL_ENDL; + return 0; + } + + U32 validitems = 0; + S32 version; + + rootp->getAttributeS32("version", version); + + // Check file version + if (version != CURRENT_VERSION) + { + LL_INFOS("Settings") << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << LL_ENDL; + return 0; + } + + LLXmlTreeNode* child_nodep = rootp->getFirstChild(); + while(child_nodep) + { + name = child_nodep->getName(); + + bool declared = controlExists(name); + + if (require_declaration && !declared) + { + // Declaration required, but this name not declared. + // Complain about non-empty names. + if (!name.empty()) + { + //read in to end of line + LL_WARNS("Settings") << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << LL_ENDL; + } + child_nodep = rootp->getNextChild(); + continue; + } + + // Got an item. Load it up. + // If not declared, assume it's a string + if (!declared) + { + switch(declare_as) + { + case TYPE_COL4: + declareColor4(name, LLColor4::white, LLStringUtil::null, LLControlVariable::PERSIST_NO); + break; + case TYPE_STRING: + default: + declareString(name, LLStringUtil::null, LLStringUtil::null, LLControlVariable::PERSIST_NO); + break; + } + } + + // Control name has been declared in code. + LLControlVariable *control = getControl(name); + + llassert(control); + + switch(control->mType) + { + case TYPE_F32: + { + F32 initial = 0.f; + + child_nodep->getAttributeF32("value", initial); + + control->set(initial); + validitems++; + } + break; + case TYPE_S32: + { + S32 initial = 0; + + child_nodep->getAttributeS32("value", initial); + + control->set(initial); + validitems++; + } + break; + case TYPE_U32: + { + U32 initial = 0; + child_nodep->getAttributeU32("value", initial); + control->set((LLSD::Integer) initial); + validitems++; + } + break; + case TYPE_BOOLEAN: + { + bool initial = false; + + child_nodep->getAttributeBOOL("value", initial); + control->set(initial); + + validitems++; + } + break; + case TYPE_STRING: + { + std::string string; + child_nodep->getAttributeString("value", string); + control->set(string); + validitems++; + } + break; + case TYPE_VEC3: + { + LLVector3 vector; + + child_nodep->getAttributeVector3("value", vector); + control->set(vector.getValue()); + validitems++; + } + break; + case TYPE_VEC3D: + { + LLVector3d vector; + + child_nodep->getAttributeVector3d("value", vector); + + control->set(vector.getValue()); + validitems++; + } + break; + case TYPE_QUAT: + { + LLQuaternion quat; + + child_nodep->getAttributeQuat("value", quat); + + control->set(quat.getValue()); + validitems++; + } + break; + case TYPE_RECT: + { + //RN: hack to support reading rectangles from a string + std::string rect_string; + + child_nodep->getAttributeString("value", rect_string); + std::istringstream istream(rect_string); + S32 left, bottom, width, height; + + istream >> left >> bottom >> width >> height; + + LLRect rect; + rect.setOriginAndSize(left, bottom, width, height); + + control->set(rect.getValue()); + validitems++; + } + break; + case TYPE_COL4: + { + LLColor4 color; + + child_nodep->getAttributeColor4("value", color); + control->set(color.getValue()); + validitems++; + } + break; + case TYPE_COL3: + { + LLVector3 color; + + child_nodep->getAttributeVector3("value", color); + control->set(LLColor3(color.mV).getValue()); + validitems++; + } + break; + + default: + break; + + } + + child_nodep = rootp->getNextChild(); + } + + return validitems; +} + +U32 LLControlGroup::saveToFile(const std::string& filename, bool nondefault_only) +{ + LLSD settings; + int num_saved = 0; + for (ctrl_name_table_t::iterator iter = mNameTable.begin(); + iter != mNameTable.end(); iter++) + { + LLControlVariable* control = iter->second; + if (!control) + { + LL_WARNS("Settings") << "Tried to save invalid control: " << iter->first << LL_ENDL; + } + else if( control->shouldSave(nondefault_only) ) + { + settings[iter->first]["Type"] = typeEnumToString(control->type()); + settings[iter->first]["Comment"] = control->getComment(); + settings[iter->first]["Value"] = control->getSaveValue(); + ++num_saved; + } + } + llofstream file; + file.open(filename.c_str()); + if (file.is_open()) + { + LLSDSerialize::toPrettyXML(settings, file); + file.close(); + LL_INFOS("Settings") << "Saved to " << filename << LL_ENDL; + } + else + { + // This is a warning because sometime we want to use settings files which can't be written... + LL_WARNS("Settings") << "Unable to open settings file: " << filename << LL_ENDL; + return 0; + } + return num_saved; +} + +U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_values, bool save_values) +{ + LLSD settings; + llifstream infile; + infile.open(filename.c_str()); + if(!infile.is_open()) + { + LL_WARNS("Settings") << "Cannot find file " << filename << " to load." << LL_ENDL; + return 0; + } + + 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, 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; + std::string const & name = itr->first; + LLSD const & control_map = itr->second; + + if(control_map.has("Persist")) + { + 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: + if(control_map.has("HideFromEditor")) + { + hidefromsettingseditor = control_map["HideFromEditor"].asInteger(); + } + else + { + hidefromsettingseditor = false; + } + + // If the control exists just set the value from the input file. + LLControlVariable* existing_control = getControl(name); + if(existing_control) + { + // set_default_values is true when we're loading the initial, + // immutable files from app_settings, e.g. settings.xml. + if(set_default_values) + { + // Override all previously set properties of this control. + // ... except for type. The types must match. + eControlType new_type = typeStringToEnum(control_map["Type"].asString()); + if(existing_control->isType(new_type)) + { + existing_control->setDefaultValue(control_map["Value"]); + existing_control->setPersist(persist); + existing_control->setHiddenFromSettingsEditor(hidefromsettingseditor); + existing_control->setComment(control_map["Comment"].asString()); + } + else + { + LL_ERRS() << "Mismatched type of control variable '" + << name << "' found while loading '" + << filename << "'." << LL_ENDL; + } + } + else if(existing_control->isPersisted()) + { + // save_values is specifically false for (e.g.) + // SessionSettingsFile and UserSessionSettingsFile -- in other + // words, for a file that's supposed to be transient. + existing_control->setValue(control_map["Value"], save_values); + } + // *NOTE: If not persisted and not setting defaults, + // the value should not get loaded. + } + else + { + // We've never seen this control before. Either we're loading up + // the initial set of default settings files (set_default_values) + // -- or we're loading user settings last saved by a viewer that + // supports a superset of the variables we know. + // CHOP-962: if we're loading an unrecognized user setting, make + // sure we save it later. If you try an experimental viewer, tweak + // a new setting, briefly revert to an old viewer, then return to + // the new one, we don't want the old viewer to discard the + // setting you changed. + if (! set_default_values) + { + // Using PERSIST_ALWAYS insists that saveToFile() (which calls + // LLControlVariable::shouldSave()) must save this control + // variable regardless of its value. We can safely set this + // LLControlVariable persistent because the 'persistent' flag + // is not itself persisted! + persist = LLControlVariable::PERSIST_ALWAYS; + // We want to mention unrecognized user settings variables + // (e.g. from a newer version of the viewer) in the log. But + // we also arrive here for Boolean variables generated by + // the notifications subsystem when the user checks "Don't + // show me this again." These aren't declared in settings.xml; + // they're actually named for the notification they suppress. + // We don't want to mention those. Apologies, this is a bit of + // a hack: we happen to know that user settings go into an + // LLControlGroup whose name is "Global". + if (getKey() == "Global") + { + LL_INFOS("LLControlGroup") << "preserving unrecognized " << getKey() + << " settings variable " << name << LL_ENDL; + } + } + + declareControl(name, + typeStringToEnum(control_map["Type"].asString()), + control_map["Value"], + control_map["Comment"].asString(), + persist, + hidefromsettingseditor + ); + } + + ++validitems; + } + + LL_DEBUGS("Settings") << "Loaded " << validitems << " settings from " << filename << LL_ENDL; + return validitems; +} + +void LLControlGroup::resetToDefaults() +{ + ctrl_name_table_t::iterator control_iter; + for (control_iter = mNameTable.begin(); + control_iter != mNameTable.end(); + ++control_iter) + { + LLControlVariable* control = (*control_iter).second; + control->resetToDefault(); + } +} + +void LLControlGroup::applyToAll(ApplyFunctor* func) +{ + for (ctrl_name_table_t::iterator iter = mNameTable.begin(); + iter != mNameTable.end(); iter++) + { + func->apply(iter->first, iter->second); + } +} + +//============================================================================ + +#ifdef TEST_HARNESS +void main() +{ + F32_CONTROL foo, getfoo; + + S32_CONTROL bar, getbar; + + BOOL_CONTROL baz; + + U32 count = gGlobals.loadFromFile("controls.ini"); + LL_INFOS("Settings") << "Loaded " << count << " controls" << LL_ENDL; + + // test insertion + foo = new LLControlVariable("gFoo", 5.f, 1.f, 20.f); + gGlobals.addEntry("gFoo", foo); + + bar = new LLControlVariable("gBar", 10, 2, 22); + gGlobals.addEntry("gBar", bar); + + baz = new LLControlVariable("gBaz", false); + gGlobals.addEntry("gBaz", baz); + + // test retrieval + getfoo = (LLControlVariable*) gGlobals.resolveName("gFoo"); + getfoo->dump(); + + getbar = (S32_CONTROL) gGlobals.resolveName("gBar"); + getbar->dump(); + + // change data + getfoo->set(10.f); + getfoo->dump(); + + // Failure modes + + // ...min > max + // badfoo = new LLControlVariable("gFoo2", 100.f, 20.f, 5.f); + + // ...initial > max + // badbar = new LLControlVariable("gBar2", 10, 20, 100000); + + // ...misspelled name + // getfoo = (F32_CONTROL) gGlobals.resolveName("fooMisspelled"); + // getfoo->dump(); + + // ...invalid data type + getfoo = (F32_CONTROL) gGlobals.resolveName("gFoo"); + getfoo->set(true); + getfoo->dump(); + + // ...out of range data + // getfoo->set(100000000.f); + // getfoo->dump(); + + // Clean Up + delete foo; + delete bar; + delete baz; +} +#endif + + +template <> eControlType get_control_type() +{ + return TYPE_U32; +} + +template <> eControlType get_control_type() +{ + return TYPE_S32; +} + +template <> eControlType get_control_type() +{ + return TYPE_F32; +} + +template <> eControlType get_control_type () +{ + return TYPE_BOOLEAN; +} + +template <> eControlType get_control_type() +{ + return TYPE_STRING; +} + +template <> eControlType get_control_type() +{ + return TYPE_VEC3; +} + +template <> eControlType get_control_type() +{ + return TYPE_VEC3D; +} + +template <> eControlType get_control_type() +{ + return TYPE_QUAT; +} + +template <> eControlType get_control_type() +{ + return TYPE_RECT; +} + +template <> eControlType get_control_type() +{ + return TYPE_COL4; +} + +template <> eControlType get_control_type() +{ + return TYPE_COL3; +} + +template <> eControlType get_control_type() +{ + return TYPE_LLSD; +} + + +template <> LLSD convert_to_llsd(const U32& in) +{ + return (LLSD::Integer)in; +} + +template <> LLSD convert_to_llsd(const LLVector3& in) +{ + return in.getValue(); +} + +template <> LLSD convert_to_llsd(const LLVector3d& in) +{ + return in.getValue(); +} +template <> LLSD convert_to_llsd(const LLQuaternion& in) +{ + return in.getValue(); +} + +template <> LLSD convert_to_llsd(const LLRect& in) +{ + return in.getValue(); +} + +template <> LLSD convert_to_llsd(const LLColor4& in) +{ + return in.getValue(); +} + +template <> LLSD convert_to_llsd(const LLColor3& in) +{ + return in.getValue(); +} + +template <> LLSD convert_to_llsd(const LLColor4U& in) +{ + return in.getValue(); +} + + +template<> +bool convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) +{ + if (type == TYPE_BOOLEAN) + return sd.asBoolean(); + else + { + CONTROL_ERRS << "Invalid bool value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return false; + } +} + +template<> +S32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) +{ + if (type == TYPE_S32) + return sd.asInteger(); + else + { + CONTROL_ERRS << "Invalid S32 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return 0; + } +} + +template<> +U32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) +{ + if (type == TYPE_U32) + return sd.asInteger(); + else + { + CONTROL_ERRS << "Invalid U32 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return 0; + } +} + +template<> +F32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) +{ + if (type == TYPE_F32) + return (F32) sd.asReal(); + else + { + CONTROL_ERRS << "Invalid F32 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return 0.0f; + } +} + +template<> +std::string convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) +{ + if (type == TYPE_STRING) + return sd.asString(); + else + { + CONTROL_ERRS << "Invalid string value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return LLStringUtil::null; + } +} + +template<> +LLWString convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) +{ + return utf8str_to_wstring(convert_from_llsd(sd, type, control_name)); +} + +template<> +LLVector3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) +{ + if (type == TYPE_VEC3) + return (LLVector3)sd; + else + { + CONTROL_ERRS << "Invalid LLVector3 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return LLVector3::zero; + } +} + +template<> +LLVector3d convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) +{ + if (type == TYPE_VEC3D) + return (LLVector3d)sd; + else + { + CONTROL_ERRS << "Invalid LLVector3d value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return LLVector3d::zero; + } +} + +template<> +LLQuaternion convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) +{ + if (type == TYPE_QUAT) + return (LLQuaternion)sd; + else + { + CONTROL_ERRS << "Invalid LLQuaternion value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return LLQuaternion(); + } +} + +template<> +LLRect convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) +{ + if (type == TYPE_RECT) + return LLRect(sd); + else + { + CONTROL_ERRS << "Invalid rect value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return LLRect::null; + } +} + + +template<> +LLColor4 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) +{ + if (type == TYPE_COL4) + { + LLColor4 color(sd); + if (color.mV[VRED] < 0.f || color.mV[VRED] > 1.f) + { + LL_WARNS("Settings") << "Color " << control_name << " red value out of range: " << color << LL_ENDL; + } + else if (color.mV[VGREEN] < 0.f || color.mV[VGREEN] > 1.f) + { + LL_WARNS("Settings") << "Color " << control_name << " green value out of range: " << color << LL_ENDL; + } + else if (color.mV[VBLUE] < 0.f || color.mV[VBLUE] > 1.f) + { + LL_WARNS("Settings") << "Color " << control_name << " blue value out of range: " << color << LL_ENDL; + } + else if (color.mV[VALPHA] < 0.f || color.mV[VALPHA] > 1.f) + { + LL_WARNS("Settings") << "Color " << control_name << " alpha value out of range: " << color << LL_ENDL; + } + + return LLColor4(sd); + } + else + { + CONTROL_ERRS << "Control " << control_name << " not a color" << LL_ENDL; + return LLColor4::white; + } +} + +template<> +LLColor3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) +{ + if (type == TYPE_COL3) + return sd; + else + { + CONTROL_ERRS << "Invalid LLColor3 value for " << control_name << ": " << LLControlGroup::typeEnumToString(type) << " " << sd << LL_ENDL; + return LLColor3::white; + } +} + +template<> +LLSD convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) +{ + return sd; +} + + +#if TEST_CACHED_CONTROL + +#define DECL_LLCC(T, V) static LLCachedControl mySetting_##T("TestCachedControl"#T, V) +DECL_LLCC(U32, (U32)666); +DECL_LLCC(S32, (S32)-666); +DECL_LLCC(F32, (F32)-666.666); +DECL_LLCC(bool, true); +static LLCachedControl mySetting_string("TestCachedControlstring", "Default String Value"); +DECL_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f)); +DECL_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f)); +DECL_LLCC(LLRect, LLRect(0, 0, 100, 500)); +DECL_LLCC(LLColor4, LLColor4(0.0f, 0.5f, 1.0f)); +DECL_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f)); +DECL_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255)); + +LLSD test_llsd = LLSD()["testing1"] = LLSD()["testing2"]; +DECL_LLCC(LLSD, test_llsd); + +void test_cached_control() +{ +#define TEST_LLCC(T, V) if((T)mySetting_##T != V) LL_ERRS() << "Fail "#T << LL_ENDL + TEST_LLCC(U32, 666); + TEST_LLCC(S32, (S32)-666); + TEST_LLCC(F32, (F32)-666.666); + TEST_LLCC(bool, true); + if((std::string)mySetting_string != "Default String Value") LL_ERRS() << "Fail string" << LL_ENDL; + TEST_LLCC(LLVector3, LLVector3(1.0f, 2.0f, 3.0f)); + TEST_LLCC(LLVector3d, LLVector3d(6.0f, 5.0f, 4.0f)); + TEST_LLCC(LLRect, LLRect(0, 0, 100, 500)); + TEST_LLCC(LLColor4, LLColor4(0.0f, 0.5f, 1.0f)); + TEST_LLCC(LLColor3, LLColor3(1.0f, 0.f, 0.5f)); + TEST_LLCC(LLColor4U, LLColor4U(255, 200, 100, 255)); +//There's no LLSD comparsion for LLCC yet. TEST_LLCC(LLSD, test_llsd); +} +#endif // TEST_CACHED_CONTROL + diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index f542745b44..1b04729a82 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -1,474 +1,474 @@ -/** - * @file llcontrol.h - * @brief A mechanism for storing "control state" for a program - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLCONTROL_H -#define LL_LLCONTROL_H - -#include "llboost.h" -#include "llevent.h" -#include "llstring.h" -#include "llrect.h" -#include "llrefcount.h" -#include "llinstancetracker.h" - -#include - -// *NOTE: boost::visit_each<> generates warning 4675 on .net 2003 -// Disable the warning for the boost includes. -#if LL_WINDOWS -# if (_MSC_VER >= 1300 && _MSC_VER < 1400) -# pragma warning(push) -# pragma warning( disable : 4675 ) -# endif -#endif - -#include - -#if LL_WINDOWS - #pragma warning (push) - #pragma warning (disable : 4263) // boost::signals2::expired_slot::what() has const mismatch - #pragma warning (disable : 4264) -#endif -#include -#if LL_WINDOWS - #pragma warning (pop) -#endif - -#if LL_WINDOWS -# if (_MSC_VER >= 1300 && _MSC_VER < 1400) -# pragma warning(pop) -# endif -#endif - -class LLVector3; -class LLVector3d; -class LLQuaternion; -class LLColor4; -class LLColor3; - -// if this is changed, also modify mTypeString in llcontrol.h -typedef enum e_control_type -{ - TYPE_U32 = 0, - TYPE_S32, - TYPE_F32, - TYPE_BOOLEAN, - TYPE_STRING, - TYPE_VEC3, - TYPE_VEC3D, - TYPE_QUAT, - TYPE_RECT, - TYPE_COL4, - TYPE_COL3, - TYPE_LLSD, - TYPE_COUNT -} eControlType; - -class LLControlVariable : public LLRefCount -{ - LOG_CLASS(LLControlVariable); - - friend class LLControlGroup; - -public: - typedef boost::signals2::signal validate_signal_t; - typedef boost::signals2::signal commit_signal_t; - - enum ePersist - { - PERSIST_NO, // don't save this var - PERSIST_NONDFT, // save this var if differs from default - PERSIST_ALWAYS // save this var even if has default value - }; - -private: - std::string mName; - std::string mComment; - eControlType mType; - ePersist mPersist; - bool mHideFromSettingsEditor; - std::vector mValues; - - commit_signal_t mCommitSignal; - validate_signal_t mValidateSignal; - -public: - LLControlVariable(const std::string& name, eControlType type, - LLSD initial, const std::string& comment, - ePersist persist = PERSIST_NONDFT, bool hidefromsettingseditor = false); - - virtual ~LLControlVariable(); - - const std::string& getName() const { return mName; } - const std::string& getComment() const { return mComment; } - - eControlType type() { return mType; } - bool isType(eControlType tp) { return tp == mType; } - - void resetToDefault(bool fire_signal = false); - - commit_signal_t* getSignal() { return &mCommitSignal; } // shorthand for commit signal - commit_signal_t* getCommitSignal() { return &mCommitSignal; } - validate_signal_t* getValidateSignal() { return &mValidateSignal; } - - bool isDefault() { return (mValues.size() == 1); } - bool shouldSave(bool nondefault_only); - bool isPersisted() { return mPersist != PERSIST_NO; } - bool isHiddenFromSettingsEditor() { return mHideFromSettingsEditor; } - LLSD get() const { return getValue(); } - LLSD getValue() const { return mValues.back(); } - LLSD getDefault() const { return mValues.front(); } - LLSD getSaveValue() const; - - void set(const LLSD& val) { setValue(val); } - void setValue(const LLSD& value, bool saved_value = true); - void setDefaultValue(const LLSD& value); - void setPersist(ePersist); - void setHiddenFromSettingsEditor(bool hide); - void setComment(const std::string& comment); - -private: - void firePropertyChanged(const LLSD &pPreviousValue) - { - mCommitSignal(this, mValues.back(), pPreviousValue); - } - LLSD getComparableValue(const LLSD& value); - bool llsd_compare(const LLSD& a, const LLSD & b); -}; - -typedef LLPointer LLControlVariablePtr; - -//! Helper functions for converting between static types and LLControl values -template -eControlType get_control_type() -{ - LL_WARNS() << "Usupported control type: " << typeid(T).name() << "." << LL_ENDL; - return TYPE_COUNT; -} - -template -LLSD convert_to_llsd(const T& in) -{ - // default implementation - return LLSD(in); -} - -template -T convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) -{ - // needs specialization - return T(sd); -} - -//const U32 STRING_CACHE_SIZE = 10000; -class LLControlGroup : public LLInstanceTracker -{ - LOG_CLASS(LLControlGroup); - -protected: - typedef std::map ctrl_name_table_t; - ctrl_name_table_t mNameTable; - static const std::string mTypeString[TYPE_COUNT]; - -public: - static eControlType typeStringToEnum(const std::string& typestr); - static std::string typeEnumToString(eControlType typeenum); - - LLControlGroup(const std::string& name); - ~LLControlGroup(); - void cleanup(); - - LLControlVariablePtr getControl(std::string_view name); - - struct ApplyFunctor - { - virtual ~ApplyFunctor() {}; - virtual void apply(const std::string& name, LLControlVariable* control) = 0; - }; - void applyToAll(ApplyFunctor* func); - - LLControlVariable* declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, bool hidefromsettingseditor = false); - LLControlVariable* declareU32(const std::string& name, U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareS32(const std::string& name, S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareF32(const std::string& name, F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareBOOL(const std::string& name, bool initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareQuat(const std::string& name, const LLQuaternion &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - LLControlVariable* declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); - - std::string getString(std::string_view name); - std::string getText(std::string_view name); - bool getBOOL(std::string_view name); - S32 getS32(std::string_view name); - F32 getF32(std::string_view name); - U32 getU32(std::string_view name); - - LLWString getWString(std::string_view name); - LLVector3 getVector3(std::string_view name); - LLVector3d getVector3d(std::string_view name); - LLRect getRect(std::string_view name); - LLSD getLLSD(std::string_view name); - LLQuaternion getQuaternion(std::string_view name); - - LLColor4 getColor(std::string_view name); - LLColor4 getColor4(std::string_view name); - LLColor3 getColor3(std::string_view name); - - LLSD asLLSD(bool diffs_only); - - // generic getter - template T get(std::string_view name) - { - LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; - LLControlVariable* control = getControl(name); - LLSD value; - eControlType type = TYPE_COUNT; - - if (control) - { - value = control->get(); - type = control->type(); - } - else - { - LL_WARNS() << "Control " << name << " not found." << LL_ENDL; - return T(); - } - return convert_from_llsd(value, type, name); - } - - void setBOOL(std::string_view name, bool val); - void setS32(std::string_view name, S32 val); - void setF32(std::string_view name, F32 val); - void setU32(std::string_view name, U32 val); - void setString(std::string_view name, const std::string& val); - void setVector3(std::string_view name, const LLVector3 &val); - void setVector3d(std::string_view name, const LLVector3d &val); - void setQuaternion(std::string_view name, const LLQuaternion &val); - void setRect(std::string_view name, const LLRect &val); - void setColor4(std::string_view name, const LLColor4 &val); - void setLLSD(std::string_view name, const LLSD& val); - - // type agnostic setter that takes LLSD - void setUntypedValue(std::string_view name, const LLSD& val); - - // generic setter - template void set(std::string_view name, const T& val) - { - LLControlVariable* control = getControl(name); - - if (control && control->isType(get_control_type())) - { - control->set(convert_to_llsd(val)); - } - else - { - LL_WARNS() << "Invalid control " << name << LL_ENDL; - } - } - - bool controlExists(const std::string& name); - - // 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, 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(); - void incrCount(std::string_view name); - - bool mSettingsProfile; -}; - - -//! Publish/Subscribe object to interact with LLControlGroups. - -//! Use an LLCachedControl instance to connect to a LLControlVariable -//! without have to manually create and bind a listener to a local -//! object. -template -class LLControlCache : public LLRefCount, public LLInstanceTracker, std::string> -{ -public: - // This constructor will declare a control if it doesn't exist in the contol group - LLControlCache(LLControlGroup& group, - const std::string& name, - const T& default_value, - const std::string& comment) - : LLInstanceTracker, std::string >(name) - { - if(!group.controlExists(name)) - { - if(!declareTypedControl(group, name, default_value, comment)) - { - LL_ERRS() << "The control could not be created!!!" << LL_ENDL; - } - } - - bindToControl(group, name); - } - - LLControlCache(LLControlGroup& group, - const std::string& name) - : LLInstanceTracker, std::string >(name) - { - if(!group.controlExists(name)) - { - LL_ERRS() << "Control named " << name << "not found." << LL_ENDL; - } - - bindToControl(group, name); - } - - ~LLControlCache() - { - } - - const T& getValue() const { return mCachedValue; } - -private: - void bindToControl(LLControlGroup& group, const std::string& name) - { - LLControlVariablePtr controlp = group.getControl(name); - mType = controlp->type(); - mCachedValue = convert_from_llsd(controlp->get(), mType, name); - - // Add a listener to the controls signal... - // NOTE: All listeners connected to 0 group, for guaranty that variable handlers (gSavedSettings) call last - mConnection = controlp->getSignal()->connect(0, - boost::bind(&LLControlCache::handleValueChange, this, _2) - ); - mType = controlp->type(); - } - bool declareTypedControl(LLControlGroup& group, - const std::string& name, - const T& default_value, - const std::string& comment) - { - LLSD init_value; - eControlType type = get_control_type(); - init_value = convert_to_llsd(default_value); - if(type < TYPE_COUNT) - { - group.declareControl(name, type, init_value, comment, LLControlVariable::PERSIST_NO); - return true; - } - return false; - } - - bool handleValueChange(const LLSD& newvalue) - { - mCachedValue = convert_from_llsd(newvalue, mType, ""); - return true; - } - -private: - T mCachedValue; - eControlType mType; - boost::signals2::scoped_connection mConnection; -}; - -template -class LLCachedControl -{ -public: - LLCachedControl(LLControlGroup& group, - const std::string& name, - const T& default_value, - const std::string& comment = "Declared In Code") - { - mCachedControlPtr = LLControlCache::getInstance(name).get(); - if (! mCachedControlPtr) - { - mCachedControlPtr = new LLControlCache(group, name, default_value, comment); - } - } - - LLCachedControl(LLControlGroup& group, - const std::string& name) - { - mCachedControlPtr = LLControlCache::getInstance(name).get(); - if (! mCachedControlPtr) - { - mCachedControlPtr = new LLControlCache(group, name); - } - } - - operator const T&() const { return mCachedControlPtr->getValue(); } - operator boost::function () const { return boost::function(*this); } - const T& operator()() { return mCachedControlPtr->getValue(); } - -private: - LLPointer > mCachedControlPtr; -}; - -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); -template <> eControlType get_control_type(); - -template <> LLSD convert_to_llsd(const U32& in); -template <> LLSD convert_to_llsd(const LLVector3& in); -template <> LLSD convert_to_llsd(const LLVector3d& in); -template <> LLSD convert_to_llsd(const LLQuaternion& in); -template <> LLSD convert_to_llsd(const LLRect& in); -template <> LLSD convert_to_llsd(const LLColor4& in); -template <> LLSD convert_to_llsd(const LLColor3& in); - -template<> std::string convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template<> LLWString convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template<> LLVector3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template<> LLVector3d convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template<> LLQuaternion convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template<> LLRect convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template<> bool convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template<> S32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template<> F32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template<> U32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template<> LLColor3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template<> LLColor4 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); -template<> LLSD convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); - -//#define TEST_CACHED_CONTROL 1 -#ifdef TEST_CACHED_CONTROL -void test_cached_control(); -#endif // TEST_CACHED_CONTROL - -#endif +/** + * @file llcontrol.h + * @brief A mechanism for storing "control state" for a program + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLCONTROL_H +#define LL_LLCONTROL_H + +#include "llboost.h" +#include "llevent.h" +#include "llstring.h" +#include "llrect.h" +#include "llrefcount.h" +#include "llinstancetracker.h" + +#include + +// *NOTE: boost::visit_each<> generates warning 4675 on .net 2003 +// Disable the warning for the boost includes. +#if LL_WINDOWS +# if (_MSC_VER >= 1300 && _MSC_VER < 1400) +# pragma warning(push) +# pragma warning( disable : 4675 ) +# endif +#endif + +#include + +#if LL_WINDOWS + #pragma warning (push) + #pragma warning (disable : 4263) // boost::signals2::expired_slot::what() has const mismatch + #pragma warning (disable : 4264) +#endif +#include +#if LL_WINDOWS + #pragma warning (pop) +#endif + +#if LL_WINDOWS +# if (_MSC_VER >= 1300 && _MSC_VER < 1400) +# pragma warning(pop) +# endif +#endif + +class LLVector3; +class LLVector3d; +class LLQuaternion; +class LLColor4; +class LLColor3; + +// if this is changed, also modify mTypeString in llcontrol.h +typedef enum e_control_type +{ + TYPE_U32 = 0, + TYPE_S32, + TYPE_F32, + TYPE_BOOLEAN, + TYPE_STRING, + TYPE_VEC3, + TYPE_VEC3D, + TYPE_QUAT, + TYPE_RECT, + TYPE_COL4, + TYPE_COL3, + TYPE_LLSD, + TYPE_COUNT +} eControlType; + +class LLControlVariable : public LLRefCount +{ + LOG_CLASS(LLControlVariable); + + friend class LLControlGroup; + +public: + typedef boost::signals2::signal validate_signal_t; + typedef boost::signals2::signal commit_signal_t; + + enum ePersist + { + PERSIST_NO, // don't save this var + PERSIST_NONDFT, // save this var if differs from default + PERSIST_ALWAYS // save this var even if has default value + }; + +private: + std::string mName; + std::string mComment; + eControlType mType; + ePersist mPersist; + bool mHideFromSettingsEditor; + std::vector mValues; + + commit_signal_t mCommitSignal; + validate_signal_t mValidateSignal; + +public: + LLControlVariable(const std::string& name, eControlType type, + LLSD initial, const std::string& comment, + ePersist persist = PERSIST_NONDFT, bool hidefromsettingseditor = false); + + virtual ~LLControlVariable(); + + const std::string& getName() const { return mName; } + const std::string& getComment() const { return mComment; } + + eControlType type() { return mType; } + bool isType(eControlType tp) { return tp == mType; } + + void resetToDefault(bool fire_signal = false); + + commit_signal_t* getSignal() { return &mCommitSignal; } // shorthand for commit signal + commit_signal_t* getCommitSignal() { return &mCommitSignal; } + validate_signal_t* getValidateSignal() { return &mValidateSignal; } + + bool isDefault() { return (mValues.size() == 1); } + bool shouldSave(bool nondefault_only); + bool isPersisted() { return mPersist != PERSIST_NO; } + bool isHiddenFromSettingsEditor() { return mHideFromSettingsEditor; } + LLSD get() const { return getValue(); } + LLSD getValue() const { return mValues.back(); } + LLSD getDefault() const { return mValues.front(); } + LLSD getSaveValue() const; + + void set(const LLSD& val) { setValue(val); } + void setValue(const LLSD& value, bool saved_value = true); + void setDefaultValue(const LLSD& value); + void setPersist(ePersist); + void setHiddenFromSettingsEditor(bool hide); + void setComment(const std::string& comment); + +private: + void firePropertyChanged(const LLSD &pPreviousValue) + { + mCommitSignal(this, mValues.back(), pPreviousValue); + } + LLSD getComparableValue(const LLSD& value); + bool llsd_compare(const LLSD& a, const LLSD & b); +}; + +typedef LLPointer LLControlVariablePtr; + +//! Helper functions for converting between static types and LLControl values +template +eControlType get_control_type() +{ + LL_WARNS() << "Usupported control type: " << typeid(T).name() << "." << LL_ENDL; + return TYPE_COUNT; +} + +template +LLSD convert_to_llsd(const T& in) +{ + // default implementation + return LLSD(in); +} + +template +T convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name) +{ + // needs specialization + return T(sd); +} + +//const U32 STRING_CACHE_SIZE = 10000; +class LLControlGroup : public LLInstanceTracker +{ + LOG_CLASS(LLControlGroup); + +protected: + typedef std::map ctrl_name_table_t; + ctrl_name_table_t mNameTable; + static const std::string mTypeString[TYPE_COUNT]; + +public: + static eControlType typeStringToEnum(const std::string& typestr); + static std::string typeEnumToString(eControlType typeenum); + + LLControlGroup(const std::string& name); + ~LLControlGroup(); + void cleanup(); + + LLControlVariablePtr getControl(std::string_view name); + + struct ApplyFunctor + { + virtual ~ApplyFunctor() {}; + virtual void apply(const std::string& name, LLControlVariable* control) = 0; + }; + void applyToAll(ApplyFunctor* func); + + LLControlVariable* declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, bool hidefromsettingseditor = false); + LLControlVariable* declareU32(const std::string& name, U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareS32(const std::string& name, S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareF32(const std::string& name, F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareBOOL(const std::string& name, bool initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareQuat(const std::string& name, const LLQuaternion &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + LLControlVariable* declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT); + + std::string getString(std::string_view name); + std::string getText(std::string_view name); + bool getBOOL(std::string_view name); + S32 getS32(std::string_view name); + F32 getF32(std::string_view name); + U32 getU32(std::string_view name); + + LLWString getWString(std::string_view name); + LLVector3 getVector3(std::string_view name); + LLVector3d getVector3d(std::string_view name); + LLRect getRect(std::string_view name); + LLSD getLLSD(std::string_view name); + LLQuaternion getQuaternion(std::string_view name); + + LLColor4 getColor(std::string_view name); + LLColor4 getColor4(std::string_view name); + LLColor3 getColor3(std::string_view name); + + LLSD asLLSD(bool diffs_only); + + // generic getter + template T get(std::string_view name) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; + LLControlVariable* control = getControl(name); + LLSD value; + eControlType type = TYPE_COUNT; + + if (control) + { + value = control->get(); + type = control->type(); + } + else + { + LL_WARNS() << "Control " << name << " not found." << LL_ENDL; + return T(); + } + return convert_from_llsd(value, type, name); + } + + void setBOOL(std::string_view name, bool val); + void setS32(std::string_view name, S32 val); + void setF32(std::string_view name, F32 val); + void setU32(std::string_view name, U32 val); + void setString(std::string_view name, const std::string& val); + void setVector3(std::string_view name, const LLVector3 &val); + void setVector3d(std::string_view name, const LLVector3d &val); + void setQuaternion(std::string_view name, const LLQuaternion &val); + void setRect(std::string_view name, const LLRect &val); + void setColor4(std::string_view name, const LLColor4 &val); + void setLLSD(std::string_view name, const LLSD& val); + + // type agnostic setter that takes LLSD + void setUntypedValue(std::string_view name, const LLSD& val); + + // generic setter + template void set(std::string_view name, const T& val) + { + LLControlVariable* control = getControl(name); + + if (control && control->isType(get_control_type())) + { + control->set(convert_to_llsd(val)); + } + else + { + LL_WARNS() << "Invalid control " << name << LL_ENDL; + } + } + + bool controlExists(const std::string& name); + + // 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, 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(); + void incrCount(std::string_view name); + + bool mSettingsProfile; +}; + + +//! Publish/Subscribe object to interact with LLControlGroups. + +//! Use an LLCachedControl instance to connect to a LLControlVariable +//! without have to manually create and bind a listener to a local +//! object. +template +class LLControlCache : public LLRefCount, public LLInstanceTracker, std::string> +{ +public: + // This constructor will declare a control if it doesn't exist in the contol group + LLControlCache(LLControlGroup& group, + const std::string& name, + const T& default_value, + const std::string& comment) + : LLInstanceTracker, std::string >(name) + { + if(!group.controlExists(name)) + { + if(!declareTypedControl(group, name, default_value, comment)) + { + LL_ERRS() << "The control could not be created!!!" << LL_ENDL; + } + } + + bindToControl(group, name); + } + + LLControlCache(LLControlGroup& group, + const std::string& name) + : LLInstanceTracker, std::string >(name) + { + if(!group.controlExists(name)) + { + LL_ERRS() << "Control named " << name << "not found." << LL_ENDL; + } + + bindToControl(group, name); + } + + ~LLControlCache() + { + } + + const T& getValue() const { return mCachedValue; } + +private: + void bindToControl(LLControlGroup& group, const std::string& name) + { + LLControlVariablePtr controlp = group.getControl(name); + mType = controlp->type(); + mCachedValue = convert_from_llsd(controlp->get(), mType, name); + + // Add a listener to the controls signal... + // NOTE: All listeners connected to 0 group, for guaranty that variable handlers (gSavedSettings) call last + mConnection = controlp->getSignal()->connect(0, + boost::bind(&LLControlCache::handleValueChange, this, _2) + ); + mType = controlp->type(); + } + bool declareTypedControl(LLControlGroup& group, + const std::string& name, + const T& default_value, + const std::string& comment) + { + LLSD init_value; + eControlType type = get_control_type(); + init_value = convert_to_llsd(default_value); + if(type < TYPE_COUNT) + { + group.declareControl(name, type, init_value, comment, LLControlVariable::PERSIST_NO); + return true; + } + return false; + } + + bool handleValueChange(const LLSD& newvalue) + { + mCachedValue = convert_from_llsd(newvalue, mType, ""); + return true; + } + +private: + T mCachedValue; + eControlType mType; + boost::signals2::scoped_connection mConnection; +}; + +template +class LLCachedControl +{ +public: + LLCachedControl(LLControlGroup& group, + const std::string& name, + const T& default_value, + const std::string& comment = "Declared In Code") + { + mCachedControlPtr = LLControlCache::getInstance(name).get(); + if (! mCachedControlPtr) + { + mCachedControlPtr = new LLControlCache(group, name, default_value, comment); + } + } + + LLCachedControl(LLControlGroup& group, + const std::string& name) + { + mCachedControlPtr = LLControlCache::getInstance(name).get(); + if (! mCachedControlPtr) + { + mCachedControlPtr = new LLControlCache(group, name); + } + } + + operator const T&() const { return mCachedControlPtr->getValue(); } + operator boost::function () const { return boost::function(*this); } + const T& operator()() { return mCachedControlPtr->getValue(); } + +private: + LLPointer > mCachedControlPtr; +}; + +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); +template <> eControlType get_control_type(); + +template <> LLSD convert_to_llsd(const U32& in); +template <> LLSD convert_to_llsd(const LLVector3& in); +template <> LLSD convert_to_llsd(const LLVector3d& in); +template <> LLSD convert_to_llsd(const LLQuaternion& in); +template <> LLSD convert_to_llsd(const LLRect& in); +template <> LLSD convert_to_llsd(const LLColor4& in); +template <> LLSD convert_to_llsd(const LLColor3& in); + +template<> std::string convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> LLWString convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> LLVector3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> LLVector3d convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> LLQuaternion convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> LLRect convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> bool convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> S32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> F32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> U32 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> LLColor3 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> LLColor4 convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); +template<> LLSD convert_from_llsd(const LLSD& sd, eControlType type, std::string_view control_name); + +//#define TEST_CACHED_CONTROL 1 +#ifdef TEST_CACHED_CONTROL +void test_cached_control(); +#endif // TEST_CACHED_CONTROL + +#endif diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index e7ea5a9fad..5e98af8412 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -1,3268 +1,3268 @@ -/** - * @file llxmlnode.cpp - * @author Tom Yedwab - * @brief LLXMLNode implementation - * - * $LicenseInfo:firstyear=2005&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include -#include - -#include "llxmlnode.h" - -#include "v3color.h" -#include "v4color.h" -#include "v4coloru.h" -#include "v3math.h" -#include "v3dmath.h" -#include "v4math.h" -#include "llquaternion.h" -#include "llstring.h" -#include "lluuid.h" -#include "lldir.h" - -// static -bool LLXMLNode::sStripEscapedStrings = true; -bool LLXMLNode::sStripWhitespaceValues = false; - -LLXMLNode::LLXMLNode() : - mID(""), - mParser(NULL), - mIsAttribute(false), - mVersionMajor(0), - mVersionMinor(0), - mLength(0), - mPrecision(64), - mType(TYPE_CONTAINER), - mEncoding(ENCODING_DEFAULT), - mLineNumber(-1), - mParent(NULL), - mChildren(NULL), - mAttributes(), - mPrev(NULL), - mNext(NULL), - mName(NULL), - mValue(""), - mDefault(NULL) -{ -} - -LLXMLNode::LLXMLNode(const char* name, bool is_attribute) : - mID(""), - mParser(NULL), - mIsAttribute(is_attribute), - mVersionMajor(0), - mVersionMinor(0), - mLength(0), - mPrecision(64), - mType(TYPE_CONTAINER), - mEncoding(ENCODING_DEFAULT), - mLineNumber(-1), - mParent(NULL), - mChildren(NULL), - mAttributes(), - mPrev(NULL), - mNext(NULL), - mValue(""), - mDefault(NULL) -{ - mName = gStringTable.addStringEntry(name); -} - -LLXMLNode::LLXMLNode(LLStringTableEntry* name, bool is_attribute) : - mID(""), - mParser(NULL), - mIsAttribute(is_attribute), - mVersionMajor(0), - mVersionMinor(0), - mLength(0), - mPrecision(64), - mType(TYPE_CONTAINER), - mEncoding(ENCODING_DEFAULT), - mLineNumber(-1), - mParent(NULL), - mChildren(NULL), - mAttributes(), - mPrev(NULL), - mNext(NULL), - mName(name), - mValue(""), - mDefault(NULL) -{ -} - -// copy constructor (except for the children) -LLXMLNode::LLXMLNode(const LLXMLNode& rhs) : - mID(rhs.mID), - mIsAttribute(rhs.mIsAttribute), - mVersionMajor(rhs.mVersionMajor), - mVersionMinor(rhs.mVersionMinor), - mLength(rhs.mLength), - mPrecision(rhs.mPrecision), - mType(rhs.mType), - mEncoding(rhs.mEncoding), - mLineNumber(0), - mParser(NULL), - mParent(NULL), - mChildren(NULL), - mAttributes(), - mPrev(NULL), - mNext(NULL), - mName(rhs.mName), - mValue(rhs.mValue), - mDefault(rhs.mDefault) -{ -} - -// returns a new copy of this node and all its children -LLXMLNodePtr LLXMLNode::deepCopy() -{ - LLXMLNodePtr newnode = LLXMLNodePtr(new LLXMLNode(*this)); - if (mChildren.notNull()) - { - 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::iterator iter = mAttributes.begin(); - iter != mAttributes.end(); ++iter) - { - LLXMLNodePtr temp_ptr_for_gcc(iter->second->deepCopy()); - newnode->addChild(temp_ptr_for_gcc); - } - - return newnode; -} - -// virtual -LLXMLNode::~LLXMLNode() -{ - // Strictly speaking none of this should be required execept 'delete mChildren'... - // Sadly, that's only true if we hadn't had reference-counted smart pointers linked - // in three different directions. This entire class is a frightening, hard-to-maintain - // mess. - if (mChildren.notNull()) - { - for (LLXMLChildList::iterator iter = mChildren->map.begin(); - iter != mChildren->map.end(); ++iter) - { - LLXMLNodePtr child = iter->second; - child->mParent = NULL; - child->mNext = NULL; - child->mPrev = NULL; - } - mChildren->map.clear(); - mChildren->head = NULL; - mChildren->tail = NULL; - mChildren = NULL; - } - for (LLXMLAttribList::iterator iter = mAttributes.begin(); - iter != mAttributes.end(); ++iter) - { - LLXMLNodePtr attr = iter->second; - attr->mParent = NULL; - attr->mNext = NULL; - attr->mPrev = NULL; - } - llassert(mParent == NULL); - mDefault = NULL; -} - -bool LLXMLNode::isNull() -{ - return (mName == NULL); -} - -// protected -bool LLXMLNode::removeChild(LLXMLNode *target_child) -{ - if (!target_child) - { - return false; - } - if (target_child->mIsAttribute) - { - LLXMLAttribList::iterator children_itr = mAttributes.find(target_child->mName); - if (children_itr != mAttributes.end()) - { - target_child->mParent = NULL; - mAttributes.erase(children_itr); - return true; - } - } - else if (mChildren.notNull()) - { - LLXMLChildList::iterator children_itr = mChildren->map.find(target_child->mName); - while (children_itr != mChildren->map.end()) - { - if (target_child == children_itr->second) - { - if (target_child == mChildren->head) - { - mChildren->head = target_child->mNext; - } - if (target_child == mChildren->tail) - { - mChildren->tail = target_child->mPrev; - } - - LLXMLNodePtr prev = target_child->mPrev; - LLXMLNodePtr next = target_child->mNext; - if (prev.notNull()) prev->mNext = next; - if (next.notNull()) next->mPrev = prev; - - target_child->mPrev = NULL; - target_child->mNext = NULL; - target_child->mParent = NULL; - mChildren->map.erase(children_itr); - if (mChildren->map.empty()) - { - mChildren = NULL; - } - return true; - } - else if (children_itr->first != target_child->mName) - { - break; - } - else - { - ++children_itr; - } - } - } - return false; -} - -void LLXMLNode::addChild(LLXMLNodePtr& new_child) -{ - if (new_child->mParent != NULL) - { - if (new_child->mParent == this) - { - return; - } - new_child->mParent->removeChild(new_child); - } - - new_child->mParent = this; - if (new_child->mIsAttribute) - { - LLXMLAttribList::iterator found_it = mAttributes.find(new_child->mName); - if (found_it != mAttributes.end()) - { - removeChild(found_it->second); - } - mAttributes.insert(std::make_pair(new_child->mName, new_child)); - } - else - { - if (mChildren.isNull()) - { - mChildren = new LLXMLChildren(); - mChildren->head = new_child; - mChildren->tail = new_child; - } - mChildren->map.insert(std::make_pair(new_child->mName, new_child)); - - if (mChildren->tail != new_child) - { - mChildren->tail->mNext = new_child; - new_child->mPrev = mChildren->tail; - mChildren->tail = new_child; - } - } - - new_child->updateDefault(); -} - -// virtual -LLXMLNodePtr LLXMLNode::createChild(const char* name, bool is_attribute) -{ - return createChild(gStringTable.addStringEntry(name), is_attribute); -} - -// virtual -LLXMLNodePtr LLXMLNode::createChild(LLStringTableEntry* name, bool is_attribute) -{ - LLXMLNodePtr ret(new LLXMLNode(name, is_attribute)); - ret->mID.clear(); - - addChild(ret); - return ret; -} - -bool LLXMLNode::deleteChild(LLXMLNode *child) -{ - if (removeChild(child)) - { - return true; - } - return false; -} - -void LLXMLNode::setParent(LLXMLNodePtr& new_parent) -{ - if (new_parent.notNull()) - { - LLXMLNodePtr this_ptr(this); - new_parent->addChild(this_ptr); - } - else - { - if (mParent != NULL) - { - LLXMLNodePtr old_parent = mParent; - mParent = NULL; - old_parent->removeChild(this); - } - } -} - - -void LLXMLNode::updateDefault() -{ - if (mParent != NULL && !mParent->mDefault.isNull()) - { - mDefault = NULL; - - // Find default value in parent's default tree - if (!mParent->mDefault.isNull()) - { - findDefault(mParent->mDefault); - } - } - - if (mChildren.notNull()) - { - LLXMLChildList::const_iterator children_itr; - LLXMLChildList::const_iterator children_end = mChildren->map.end(); - for (children_itr = mChildren->map.begin(); children_itr != children_end; ++children_itr) - { - LLXMLNodePtr child = (*children_itr).second; - child->updateDefault(); - } - } -} - -void XMLCALL StartXMLNode(void *userData, - const XML_Char *name, - const XML_Char **atts) -{ - // Create a new node - LLXMLNode *new_node_ptr = new LLXMLNode(name, false); - - LLXMLNodePtr new_node = new_node_ptr; - new_node->mID.clear(); - LLXMLNodePtr ptr_new_node = new_node; - - // Set the parent-child relationship with the current active node - LLXMLNode* parent = (LLXMLNode *)userData; - - if (NULL == parent) - { - LL_WARNS() << "parent (userData) is NULL; aborting function" << LL_ENDL; - return; - } - - new_node_ptr->mParser = parent->mParser; - new_node_ptr->setLineNumber(XML_GetCurrentLineNumber(*new_node_ptr->mParser)); - - // Set the current active node to the new node - XML_Parser *parser = parent->mParser; - XML_SetUserData(*parser, (void *)new_node_ptr); - - // Parse attributes - U32 pos = 0; - while (atts[pos] != NULL) - { - std::string attr_name = atts[pos]; - std::string attr_value = atts[pos+1]; - - // Special cases - if ('i' == attr_name[0] && "id" == attr_name) - { - new_node->mID = attr_value; - } - else if ('v' == attr_name[0] && "version" == attr_name) - { - U32 version_major = 0; - U32 version_minor = 0; - if (sscanf(attr_value.c_str(), "%d.%d", &version_major, &version_minor) > 0) - { - new_node->mVersionMajor = version_major; - new_node->mVersionMinor = version_minor; - } - } - else if (('s' == attr_name[0] && "size" == attr_name) || ('l' == attr_name[0] && "length" == attr_name)) - { - U32 length; - if (sscanf(attr_value.c_str(), "%d", &length) > 0) - { - new_node->mLength = length; - } - } - else if ('p' == attr_name[0] && "precision" == attr_name) - { - U32 precision; - if (sscanf(attr_value.c_str(), "%d", &precision) > 0) - { - new_node->mPrecision = precision; - } - } - else if ('t' == attr_name[0] && "type" == attr_name) - { - if ("boolean" == attr_value) - { - new_node->mType = LLXMLNode::TYPE_BOOLEAN; - } - else if ("integer" == attr_value) - { - new_node->mType = LLXMLNode::TYPE_INTEGER; - } - else if ("float" == attr_value) - { - new_node->mType = LLXMLNode::TYPE_FLOAT; - } - else if ("string" == attr_value) - { - new_node->mType = LLXMLNode::TYPE_STRING; - } - else if ("uuid" == attr_value) - { - new_node->mType = LLXMLNode::TYPE_UUID; - } - else if ("noderef" == attr_value) - { - new_node->mType = LLXMLNode::TYPE_NODEREF; - } - } - else if ('e' == attr_name[0] && "encoding" == attr_name) - { - if ("decimal" == attr_value) - { - new_node->mEncoding = LLXMLNode::ENCODING_DECIMAL; - } - else if ("hex" == attr_value) - { - new_node->mEncoding = LLXMLNode::ENCODING_HEX; - } - /*else if (attr_value == "base32") - { - new_node->mEncoding = LLXMLNode::ENCODING_BASE32; - }*/ - } - - // only one attribute child per description - LLXMLNodePtr attr_node; - if (!new_node->getAttribute(attr_name.c_str(), attr_node, false)) - { - attr_node = new LLXMLNode(attr_name.c_str(), true); - attr_node->setLineNumber(XML_GetCurrentLineNumber(*new_node_ptr->mParser)); - } - attr_node->setValue(attr_value); - new_node->addChild(attr_node); - - pos += 2; - } - - if (parent) - { - parent->addChild(new_node); - } -} - -void XMLCALL EndXMLNode(void *userData, - const XML_Char *name) -{ - // [FUGLY] Set the current active node to the current node's parent - LLXMLNode *node = (LLXMLNode *)userData; - XML_Parser *parser = node->mParser; - XML_SetUserData(*parser, (void *)node->mParent); - // SJB: total hack: - if (LLXMLNode::sStripWhitespaceValues) - { - std::string value = node->getValue(); - bool is_empty = true; - for (std::string::size_type s = 0; s < value.length(); s++) - { - char c = value[s]; - if (c != ' ' && c != '\t' && c != '\n') - { - is_empty = false; - break; - } - } - if (is_empty) - { - value.clear(); - node->setValue(value); - } - } -} - -void XMLCALL XMLData(void *userData, - const XML_Char *s, - int len) -{ - LLXMLNode* current_node = (LLXMLNode *)userData; - std::string value = current_node->getValue(); - if (LLXMLNode::sStripEscapedStrings) - { - if (s[0] == '\"' && s[len-1] == '\"') - { - // Special-case: Escaped string. - std::string unescaped_string; - for (S32 pos=1; possetValue(value); - return; - } - } - value.append(std::string(s, len)); - current_node->setValue(value); -} - - - -// static -bool LLXMLNode::updateNode( - LLXMLNodePtr& node, - LLXMLNodePtr& update_node) -{ - - if (!node || !update_node) - { - LL_WARNS() << "Node invalid" << LL_ENDL; - return false; - } - - //update the node value - node->mValue = update_node->mValue; - - //update all attribute values - LLXMLAttribList::const_iterator itor; - - for(itor = update_node->mAttributes.begin(); itor != update_node->mAttributes.end(); ++itor) - { - const LLStringTableEntry* attribNameEntry = (*itor).first; - LLXMLNodePtr updateAttribNode = (*itor).second; - - LLXMLNodePtr attribNode; - - node->getAttribute(attribNameEntry, attribNode, 0); - - if (attribNode) - { - attribNode->mValue = updateAttribNode->mValue; - } - } - - //update all of node's children with updateNodes children that match name - LLXMLNodePtr child = node->getFirstChild(); - LLXMLNodePtr last_child = child; - LLXMLNodePtr updateChild; - - for (updateChild = update_node->getFirstChild(); updateChild.notNull(); - updateChild = updateChild->getNextSibling()) - { - while(child.notNull()) - { - std::string nodeName; - std::string updateName; - - updateChild->getAttributeString("name", updateName); - child->getAttributeString("name", nodeName); - - - //if it's a combobox there's no name, but there is a value - if (updateName.empty()) - { - updateChild->getAttributeString("value", updateName); - child->getAttributeString("value", nodeName); - } - - if ((nodeName != "") && (updateName == nodeName)) - { - updateNode(child, updateChild); - last_child = child; - child = child->getNextSibling(); - if (child.isNull()) - { - child = node->getFirstChild(); - } - break; - } - - child = child->getNextSibling(); - if (child.isNull()) - { - child = node->getFirstChild(); - } - if (child == last_child) - { - break; - } - } - } - - return true; -} - -// static -bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXMLNode* defaults_tree) -{ - // 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); - - U8* buffer = new U8[length+1]; - size_t nread = fread(buffer, 1, length, fp); - buffer[nread] = 0; - fclose(fp); - - bool rv = parseBuffer(buffer, nread, node, defaults_tree); - delete [] buffer; - return rv; -} - -// static -bool LLXMLNode::parseBuffer( - U8* buffer, - U32 length, - LLXMLNodePtr& node, - LLXMLNode* defaults) -{ - // Init - XML_Parser my_parser = XML_ParserCreate(NULL); - XML_SetElementHandler(my_parser, StartXMLNode, EndXMLNode); - XML_SetCharacterDataHandler(my_parser, XMLData); - - // Create a root node - LLXMLNode *file_node_ptr = new LLXMLNode("XML", false); - LLXMLNodePtr file_node = file_node_ptr; - - file_node->mParser = &my_parser; - - XML_SetUserData(my_parser, (void *)file_node_ptr); - - // Do the parsing - 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)) - << " on line " << XML_GetCurrentLineNumber(my_parser) - << LL_ENDL; - } - - // Deinit - XML_ParserFree(my_parser); - - if (!file_node->mChildren || file_node->mChildren->map.size() != 1) - { - LL_WARNS() << "Parse failure - wrong number of top-level nodes xml." - << LL_ENDL; - node = NULL ; - return false; - } - - LLXMLNode *return_node = file_node->mChildren->map.begin()->second; - - return_node->setDefault(defaults); - return_node->updateDefault(); - - node = return_node; - return true; -} - -// static -bool LLXMLNode::parseStream( - std::istream& str, - LLXMLNodePtr& node, - LLXMLNode* defaults) -{ - // Init - XML_Parser my_parser = XML_ParserCreate(NULL); - XML_SetElementHandler(my_parser, StartXMLNode, EndXMLNode); - XML_SetCharacterDataHandler(my_parser, XMLData); - - // Create a root node - LLXMLNode *file_node_ptr = new LLXMLNode("XML", false); - LLXMLNodePtr file_node = file_node_ptr; - - file_node->mParser = &my_parser; - - XML_SetUserData(my_parser, (void *)file_node_ptr); - - const int BUFSIZE = 1024; - U8* buffer = new U8[BUFSIZE]; - - while(str.good()) - { - str.read((char*)buffer, BUFSIZE); - int count = (int)str.gcount(); - - if (XML_Parse(my_parser, (const char *)buffer, count, !str.good()) != XML_STATUS_OK) - { - LL_WARNS() << "Error parsing xml error code: " - << XML_ErrorString(XML_GetErrorCode(my_parser)) - << " on lne " << XML_GetCurrentLineNumber(my_parser) - << LL_ENDL; - break; - } - } - - delete [] buffer; - - // Deinit - XML_ParserFree(my_parser); - - if (!file_node->mChildren || file_node->mChildren->map.size() != 1) - { - LL_WARNS() << "Parse failure - wrong number of top-level nodes xml." - << LL_ENDL; - node = NULL; - return false; - } - - LLXMLNode *return_node = file_node->mChildren->map.begin()->second; - - return_node->setDefault(defaults); - return_node->updateDefault(); - - node = return_node; - return true; -} - - -bool LLXMLNode::isFullyDefault() -{ - if (mDefault.isNull()) - { - return false; - } - bool has_default_value = (mValue == mDefault->mValue); - bool has_default_attribute = (mIsAttribute == mDefault->mIsAttribute); - bool has_default_type = mIsAttribute || (mType == mDefault->mType); - bool has_default_encoding = mIsAttribute || (mEncoding == mDefault->mEncoding); - bool has_default_precision = mIsAttribute || (mPrecision == mDefault->mPrecision); - bool has_default_length = mIsAttribute || (mLength == mDefault->mLength); - - if (has_default_value - && has_default_type - && has_default_encoding - && has_default_precision - && has_default_length - && has_default_attribute) - { - if (mChildren.notNull()) - { - LLXMLChildList::const_iterator children_itr; - LLXMLChildList::const_iterator children_end = mChildren->map.end(); - for (children_itr = mChildren->map.begin(); children_itr != children_end; ++children_itr) - { - LLXMLNodePtr child = (*children_itr).second; - if (!child->isFullyDefault()) - { - return false; - } - } - } - return true; - } - - return false; -} - -// static -bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root, - const std::vector& paths) -{ - if (paths.empty()) return false; - - std::string filename = paths.front(); - if (filename.empty()) - { - return false; - } - - if (!LLXMLNode::parseFile(filename, root, NULL)) - { - LL_WARNS() << "Problem reading UI description file: " << filename << " " << errno << LL_ENDL; - return false; - } - - LLXMLNodePtr updateRoot; - - std::vector::const_iterator itor; - - // We've already dealt with the first item, skip that one - for (itor = paths.begin() + 1; itor != paths.end(); ++itor) - { - std::string layer_filename = *itor; - if(layer_filename.empty() || layer_filename == filename) - { - // no localized version of this file, that's ok, keep looking - continue; - } - - if (!LLXMLNode::parseFile(layer_filename, updateRoot, NULL)) - { - LL_WARNS() << "Problem reading localized UI description file: " << layer_filename << LL_ENDL; - return false; - } - - std::string nodeName; - std::string updateName; - - updateRoot->getAttributeString("name", updateName); - root->getAttributeString("name", nodeName); - - if (updateName == nodeName) - { - LLXMLNode::updateNode(root, updateRoot); - } - } - - return true; -} - -// static -void LLXMLNode::writeHeaderToFile(LLFILE *out_file) -{ - fprintf(out_file, "\n"); -} - -void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent, bool use_type_decorations) -{ - if (isFullyDefault()) - { - // Don't write out nodes that are an exact match to defaults - return; - } - - std::ostringstream ostream; - writeToOstream(ostream, indent, use_type_decorations); - std::string outstring = ostream.str(); - size_t written = fwrite(outstring.c_str(), 1, outstring.length(), out_file); - if (written != outstring.length()) - { - LL_WARNS() << "Short write" << LL_ENDL; - } -} - -void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& indent, bool use_type_decorations) -{ - if (isFullyDefault()) - { - // Don't write out nodes that are an exact match to defaults - return; - } - - bool has_default_type = mDefault.isNull()?false:(mType == mDefault->mType); - bool has_default_encoding = mDefault.isNull()?false:(mEncoding == mDefault->mEncoding); - bool has_default_precision = mDefault.isNull()?false:(mPrecision == mDefault->mPrecision); - bool has_default_length = mDefault.isNull()?false:(mLength == mDefault->mLength); - - // stream the name - output_stream << indent << "<" << mName->mString << "\n"; - - if (use_type_decorations) - { - // ID - if (mID != "") - { - output_stream << indent << " id=\"" << mID << "\"\n"; - } - - // Type - if (!has_default_type) - { - switch (mType) - { - case TYPE_BOOLEAN: - output_stream << indent << " type=\"boolean\"\n"; - break; - case TYPE_INTEGER: - output_stream << indent << " type=\"integer\"\n"; - break; - case TYPE_FLOAT: - output_stream << indent << " type=\"float\"\n"; - break; - case TYPE_STRING: - output_stream << indent << " type=\"string\"\n"; - break; - case TYPE_UUID: - output_stream << indent << " type=\"uuid\"\n"; - break; - case TYPE_NODEREF: - output_stream << indent << " type=\"noderef\"\n"; - break; - default: - // default on switch(enum) eliminates a warning on linux - break; - }; - } - - // Encoding - if (!has_default_encoding) - { - switch (mEncoding) - { - case ENCODING_DECIMAL: - output_stream << indent << " encoding=\"decimal\"\n"; - break; - case ENCODING_HEX: - output_stream << indent << " encoding=\"hex\"\n"; - break; - /*case ENCODING_BASE32: - output_stream << indent << " encoding=\"base32\"\n"; - break;*/ - default: - // default on switch(enum) eliminates a warning on linux - break; - }; - } - - // Precision - if (!has_default_precision && (mType == TYPE_INTEGER || mType == TYPE_FLOAT)) - { - output_stream << indent << " precision=\"" << mPrecision << "\"\n"; - } - - // Version - if (mVersionMajor > 0 || mVersionMinor > 0) - { - output_stream << indent << " version=\"" << mVersionMajor << "." << mVersionMinor << "\"\n"; - } - - // Array length - if (!has_default_length && mLength > 0) - { - output_stream << indent << " length=\"" << mLength << "\"\n"; - } - } - - { - // Write out attributes - LLXMLAttribList::const_iterator attr_itr; - LLXMLAttribList::const_iterator attr_end = mAttributes.end(); - for (attr_itr = mAttributes.begin(); attr_itr != attr_end; ++attr_itr) - { - LLXMLNodePtr child = (*attr_itr).second; - if (child->mDefault.isNull() || child->mDefault->mValue != child->mValue) - { - std::string attr = child->mName->mString; - if (use_type_decorations - && (attr == "id" || - attr == "type" || - attr == "encoding" || - attr == "precision" || - attr == "version" || - attr == "length")) - { - continue; // skip built-in attributes - } - - std::string attr_str = llformat(" %s=\"%s\"", - attr.c_str(), - escapeXML(child->mValue).c_str()); - output_stream << indent << attr_str << "\n"; - } - } - } - - // erase last \n before attaching final > or /> - output_stream.seekp(-1, std::ios::cur); - - if (mChildren.isNull() && mValue == "") - { - output_stream << " />\n"; - return; - } - else - { - output_stream << ">\n"; - if (mChildren.notNull()) - { - // stream non-attributes - std::string next_indent = indent + " "; - for (LLXMLNode* child = getFirstChild(); child; child = child->getNextSibling()) - { - child->writeToOstream(output_stream, next_indent, use_type_decorations); - } - } - if (!mValue.empty()) - { - std::string contents = getTextContents(); - output_stream << indent << " " << escapeXML(contents) << "\n"; - } - output_stream << indent << "mString << ">\n"; - } -} - -void LLXMLNode::findName(const std::string& name, LLXMLNodeList &results) -{ - LLStringTableEntry* name_entry = gStringTable.checkStringEntry(name); - if (name_entry == mName) - { - results.insert(std::make_pair(this->mName->mString, this)); - return; - } - if (mChildren.notNull()) - { - LLXMLChildList::const_iterator children_itr; - LLXMLChildList::const_iterator children_end = mChildren->map.end(); - for (children_itr = mChildren->map.begin(); children_itr != children_end; ++children_itr) - { - LLXMLNodePtr child = (*children_itr).second; - child->findName(name_entry, results); - } - } -} - -void LLXMLNode::findName(LLStringTableEntry* name, LLXMLNodeList &results) -{ - if (name == mName) - { - results.insert(std::make_pair(this->mName->mString, this)); - return; - } - if (mChildren.notNull()) - { - LLXMLChildList::const_iterator children_itr; - LLXMLChildList::const_iterator children_end = mChildren->map.end(); - for (children_itr = mChildren->map.begin(); children_itr != children_end; ++children_itr) - { - LLXMLNodePtr child = (*children_itr).second; - child->findName(name, results); - } - } -} - -void LLXMLNode::findID(const std::string& id, LLXMLNodeList &results) -{ - if (id == mID) - { - results.insert(std::make_pair(this->mName->mString, this)); - return; - } - if (mChildren.notNull()) - { - LLXMLChildList::const_iterator children_itr; - LLXMLChildList::const_iterator children_end = mChildren->map.end(); - for (children_itr = mChildren->map.begin(); children_itr != children_end; ++children_itr) - { - LLXMLNodePtr child = (*children_itr).second; - child->findID(id, results); - } - } -} - -void LLXMLNode::scrubToTree(LLXMLNode *tree) -{ - if (!tree || tree->mChildren.isNull()) - { - return; - } - if (mChildren.notNull()) - { - std::vector to_delete_list; - LLXMLChildList::iterator itor = mChildren->map.begin(); - while (itor != mChildren->map.end()) - { - LLXMLNodePtr child = itor->second; - LLXMLNodePtr child_tree = NULL; - // Look for this child in the default's children - bool found = false; - LLXMLChildList::iterator itor2 = tree->mChildren->map.begin(); - while (itor2 != tree->mChildren->map.end()) - { - if (child->mName == itor2->second->mName) - { - child_tree = itor2->second; - found = true; - } - ++itor2; - } - if (!found) - { - to_delete_list.push_back(child); - } - else - { - child->scrubToTree(child_tree); - } - ++itor; - } - std::vector::iterator itor3; - for (itor3=to_delete_list.begin(); itor3!=to_delete_list.end(); ++itor3) - { - LLXMLNodePtr ptr; - (*itor3)->setParent(ptr); - } - } -} - -bool LLXMLNode::getChild(const char* name, LLXMLNodePtr& node, bool use_default_if_missing) -{ - return getChild(gStringTable.checkStringEntry(name), node, use_default_if_missing); -} - -bool LLXMLNode::getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, bool use_default_if_missing) -{ - if (mChildren.notNull()) - { - LLXMLChildList::const_iterator child_itr = mChildren->map.find(name); - if (child_itr != mChildren->map.end()) - { - node = (*child_itr).second; - return true; - } - } - if (use_default_if_missing && !mDefault.isNull()) - { - return mDefault->getChild(name, node, false); - } - node = NULL; - return false; -} - -void LLXMLNode::getChildren(const char* name, LLXMLNodeList &children, bool use_default_if_missing) const -{ - getChildren(gStringTable.checkStringEntry(name), children, use_default_if_missing); -} - -void LLXMLNode::getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, bool use_default_if_missing) const -{ - if (mChildren.notNull()) - { - LLXMLChildList::const_iterator child_itr = mChildren->map.find(name); - if (child_itr != mChildren->map.end()) - { - LLXMLChildList::const_iterator children_end = mChildren->map.end(); - while (child_itr != children_end) - { - LLXMLNodePtr child = (*child_itr).second; - if (name != child->mName) - { - break; - } - children.insert(std::make_pair(child->mName->mString, child)); - child_itr++; - } - } - } - if (children.size() == 0 && use_default_if_missing && !mDefault.isNull()) - { - mDefault->getChildren(name, children, false); - } -} - -// recursively walks the tree and returns all children at all nesting levels matching the name -void LLXMLNode::getDescendants(const LLStringTableEntry* name, LLXMLNodeList &children) const -{ - if (mChildren.notNull()) - { - for (LLXMLChildList::const_iterator child_itr = mChildren->map.begin(); - child_itr != mChildren->map.end(); ++child_itr) - { - LLXMLNodePtr child = (*child_itr).second; - if (name == child->mName) - { - children.insert(std::make_pair(child->mName->mString, child)); - } - // and check each child as well - child->getDescendants(name, children); - } - } -} - -bool LLXMLNode::getAttribute(const char* name, LLXMLNodePtr& node, bool use_default_if_missing) -{ - return getAttribute(gStringTable.checkStringEntry(name), node, use_default_if_missing); -} - -bool LLXMLNode::getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, bool use_default_if_missing) -{ - LLXMLAttribList::const_iterator child_itr = mAttributes.find(name); - if (child_itr != mAttributes.end()) - { - node = (*child_itr).second; - return true; - } - if (use_default_if_missing && !mDefault.isNull()) - { - return mDefault->getAttribute(name, node, false); - } - - return false; -} - -bool LLXMLNode::setAttributeString(const char* attr, const std::string& value) -{ - LLStringTableEntry* name = gStringTable.checkStringEntry(attr); - LLXMLAttribList::const_iterator child_itr = mAttributes.find(name); - if (child_itr != mAttributes.end()) - { - LLXMLNodePtr node = (*child_itr).second; - node->setValue(value); - return true; - } - return false; -} - -bool LLXMLNode::hasAttribute(const char* name ) -{ - LLXMLNodePtr node; - return getAttribute(name, node); -} - -bool LLXMLNode::getAttributeBOOL(const char* name, bool& value ) -{ - LLXMLNodePtr node; - return (getAttribute(name, node) && node->getBoolValue(1, &value)); -} - -bool LLXMLNode::getAttributeU8(const char* name, U8& value ) -{ - LLXMLNodePtr node; - return (getAttribute(name, node) && node->getByteValue(1, &value)); -} - -bool LLXMLNode::getAttributeS8(const char* name, S8& value ) -{ - LLXMLNodePtr node; - S32 val; - if (!(getAttribute(name, node) && node->getIntValue(1, &val))) - { - return false; - } - value = val; - return true; -} - -bool LLXMLNode::getAttributeU16(const char* name, U16& value ) -{ - LLXMLNodePtr node; - U32 val; - if (!(getAttribute(name, node) && node->getUnsignedValue(1, &val))) - { - return false; - } - value = val; - return true; -} - -bool LLXMLNode::getAttributeS16(const char* name, S16& value ) -{ - LLXMLNodePtr node; - S32 val; - if (!(getAttribute(name, node) && node->getIntValue(1, &val))) - { - return false; - } - value = val; - return true; -} - -bool LLXMLNode::getAttributeU32(const char* name, U32& value ) -{ - LLXMLNodePtr node; - return (getAttribute(name, node) && node->getUnsignedValue(1, &value)); -} - -bool LLXMLNode::getAttributeS32(const char* name, S32& value ) -{ - LLXMLNodePtr node; - return (getAttribute(name, node) && node->getIntValue(1, &value)); -} - -bool LLXMLNode::getAttributeF32(const char* name, F32& value ) -{ - LLXMLNodePtr node; - return (getAttribute(name, node) && node->getFloatValue(1, &value)); -} - -bool LLXMLNode::getAttributeF64(const char* name, F64& value ) -{ - LLXMLNodePtr node; - return (getAttribute(name, node) && node->getDoubleValue(1, &value)); -} - -bool LLXMLNode::getAttributeColor(const char* name, LLColor4& value ) -{ - LLXMLNodePtr node; - return (getAttribute(name, node) && node->getFloatValue(4, value.mV)); -} - -bool LLXMLNode::getAttributeColor4(const char* name, LLColor4& value ) -{ - LLXMLNodePtr node; - return (getAttribute(name, node) && node->getFloatValue(4, value.mV)); -} - -bool LLXMLNode::getAttributeColor4U(const char* name, LLColor4U& value ) -{ - LLXMLNodePtr node; - return (getAttribute(name, node) && node->getByteValue(4, value.mV)); -} - -bool LLXMLNode::getAttributeVector3(const char* name, LLVector3& value ) -{ - LLXMLNodePtr node; - return (getAttribute(name, node) && node->getFloatValue(3, value.mV)); -} - -bool LLXMLNode::getAttributeVector3d(const char* name, LLVector3d& value ) -{ - LLXMLNodePtr node; - return (getAttribute(name, node) && node->getDoubleValue(3, value.mdV)); -} - -bool LLXMLNode::getAttributeQuat(const char* name, LLQuaternion& value ) -{ - LLXMLNodePtr node; - return (getAttribute(name, node) && node->getFloatValue(4, value.mQ)); -} - -bool LLXMLNode::getAttributeUUID(const char* name, LLUUID& value ) -{ - LLXMLNodePtr node; - return (getAttribute(name, node) && node->getUUIDValue(1, &value)); -} - -bool LLXMLNode::getAttributeString(const char* name, std::string& value ) -{ - LLXMLNodePtr node; - if (!getAttribute(name, node)) - { - return false; - } - value = node->getValue(); - return true; -} - -LLXMLNodePtr LLXMLNode::getRoot() -{ - if (mParent == NULL) - { - return this; - } - return mParent->getRoot(); -} - -/*static */ -const char *LLXMLNode::skipWhitespace(const char *str) -{ - // skip whitespace characters - while (str[0] == ' ' || str[0] == '\t' || str[0] == '\n') ++str; - return str; -} - -/*static */ -const char *LLXMLNode::skipNonWhitespace(const char *str) -{ - // skip non-whitespace characters - while (str[0] != ' ' && str[0] != '\t' && str[0] != '\n' && str[0] != 0) ++str; - return str; -} - -/*static */ -const char *LLXMLNode::parseInteger(const char *str, U64 *dest, bool *is_negative, U32 precision, Encoding encoding) -{ - *dest = 0; - *is_negative = false; - - str = skipWhitespace(str); - - if (str[0] == 0) return NULL; - - if (encoding == ENCODING_DECIMAL || encoding == ENCODING_DEFAULT) - { - if (str[0] == '+') - { - ++str; - } - if (str[0] == '-') - { - *is_negative = true; - ++str; - } - - str = skipWhitespace(str); - - U64 ret = 0; - while (str[0] >= '0' && str[0] <= '9') - { - ret *= 10; - ret += str[0] - '0'; - ++str; - } - - if (str[0] == '.') - { - // If there is a fractional part, skip it - str = skipNonWhitespace(str); - } - - *dest = ret; - return str; - } - if (encoding == ENCODING_HEX) - { - U64 ret = 0; - str = skipWhitespace(str); - for (U32 pos=0; pos<(precision/4); ++pos) - { - ret <<= 4; - str = skipWhitespace(str); - if (str[0] >= '0' && str[0] <= '9') - { - ret += str[0] - '0'; - } - else if (str[0] >= 'a' && str[0] <= 'f') - { - ret += str[0] - 'a' + 10; - } - else if (str[0] >= 'A' && str[0] <= 'F') - { - ret += str[0] - 'A' + 10; - } - else - { - return NULL; - } - ++str; - } - - *dest = ret; - return str; - } - return NULL; -} - -// 25 elements - decimal expansions of 1/(2^n), multiplied by 10 each iteration -const U64 float_coeff_table[] = - { 5, 25, 125, 625, 3125, - 15625, 78125, 390625, 1953125, 9765625, - 48828125, 244140625, 1220703125, 6103515625LL, 30517578125LL, - 152587890625LL, 762939453125LL, 3814697265625LL, 19073486328125LL, 95367431640625LL, - 476837158203125LL, 2384185791015625LL, 11920928955078125LL, 59604644775390625LL, 298023223876953125LL }; - -// 36 elements - decimal expansions of 1/(2^n) after the last 28, truncated, no multiply each iteration -const U64 float_coeff_table_2[] = - { 149011611938476562LL,74505805969238281LL, - 37252902984619140LL, 18626451492309570LL, 9313225746154785LL, 4656612873077392LL, - 2328306436538696LL, 1164153218269348LL, 582076609134674LL, 291038304567337LL, - 145519152283668LL, 72759576141834LL, 36379788070917LL, 18189894035458LL, - 9094947017729LL, 4547473508864LL, 2273736754432LL, 1136868377216LL, - 568434188608LL, 284217094304LL, 142108547152LL, 71054273576LL, - 35527136788LL, 17763568394LL, 8881784197LL, 4440892098LL, - 2220446049LL, 1110223024LL, 555111512LL, 277555756LL, - 138777878, 69388939, 34694469, 17347234, - 8673617, 4336808, 2168404, 1084202, - 542101, 271050, 135525, 67762, - }; - -/*static */ -const char *LLXMLNode::parseFloat(const char *str, F64 *dest, U32 precision, Encoding encoding) -{ - str = skipWhitespace(str); - - if (str[0] == 0) return NULL; - - if (encoding == ENCODING_DECIMAL || encoding == ENCODING_DEFAULT) - { - str = skipWhitespace(str); - - if (memcmp(str, "inf", 3) == 0) - { - *(U64 *)dest = 0x7FF0000000000000ll; - return str + 3; - } - if (memcmp(str, "-inf", 4) == 0) - { - *(U64 *)dest = 0xFFF0000000000000ll; - return str + 4; - } - if (memcmp(str, "1.#INF", 6) == 0) - { - *(U64 *)dest = 0x7FF0000000000000ll; - return str + 6; - } - if (memcmp(str, "-1.#INF", 7) == 0) - { - *(U64 *)dest = 0xFFF0000000000000ll; - return str + 7; - } - - F64 negative = 1.0f; - if (str[0] == '+') - { - ++str; - } - if (str[0] == '-') - { - negative = -1.0f; - ++str; - } - - const char* base_str = str; - str = skipWhitespace(str); - - // Parse the integer part of the expression - U64 int_part = 0; - while (str[0] >= '0' && str[0] <= '9') - { - int_part *= 10; - int_part += U64(str[0] - '0'); - ++str; - } - - U64 f_part = 0;//, f_decimal = 1; - if (str[0] == '.') - { - ++str; - U64 remainder = 0; - U32 pos = 0; - // Parse the decimal part of the expression - while (str[0] >= '0' && str[0] <= '9' && pos < 25) - { - remainder = (remainder*10) + U64(str[0] - '0'); - f_part <<= 1; - //f_decimal <<= 1; - // Check the n'th bit - if (remainder >= float_coeff_table[pos]) - { - remainder -= float_coeff_table[pos]; - f_part |= 1; - } - ++pos; - ++str; - } - if (pos == 25) - { - // Drop any excessive digits - while (str[0] >= '0' && str[0] <= '9') - { - ++str; - } - } - else - { - while (pos < 25) - { - remainder *= 10; - f_part <<= 1; - //f_decimal <<= 1; - // Check the n'th bit - if (remainder >= float_coeff_table[pos]) - { - remainder -= float_coeff_table[pos]; - f_part |= 1; - } - ++pos; - } - } - pos = 0; - while (pos < 36) - { - f_part <<= 1; - //f_decimal <<= 1; - if (remainder >= float_coeff_table_2[pos]) - { - remainder -= float_coeff_table_2[pos]; - f_part |= 1; - } - ++pos; - } - } - - F64 ret = F64(int_part) + (F64(f_part)/F64(1LL<<61)); - - F64 exponent = 1.f; - if (str[0] == 'e') - { - // Scientific notation! - ++str; - U64 exp; - bool is_negative; - str = parseInteger(str, &exp, &is_negative, 64, ENCODING_DECIMAL); - if (str == NULL) - { - exp = 1; - } - F64 exp_d = F64(exp) * (is_negative?-1:1); - exponent = pow(10.0, exp_d); - } - - if (str == base_str) - { - // no digits parsed - return NULL; - } - else - { - *dest = ret*negative*exponent; - return str; - } - } - if (encoding == ENCODING_HEX) - { - U64 bytes_dest; - bool is_negative; - str = parseInteger(str, (U64 *)&bytes_dest, &is_negative, precision, ENCODING_HEX); - // Upcast to F64 - switch (precision) - { - case 32: - { - U32 short_dest = (U32)bytes_dest; - F32 ret_val = *(F32 *)&short_dest; - *dest = ret_val; - } - break; - case 64: - *dest = *(F64 *)&bytes_dest; - break; - default: - return NULL; - } - return str; - } - return NULL; -} - -U32 LLXMLNode::getBoolValue(U32 expected_length, bool *array) -{ - llassert(array); - - // Check type - accept booleans or strings - if (mType != TYPE_BOOLEAN && mType != TYPE_STRING && mType != TYPE_UNKNOWN) - { - return 0; - } - - std::string *str_array = new std::string[expected_length]; - - U32 length = getStringValue(expected_length, str_array); - - U32 ret_length = 0; - for (U32 i=0; imString << "' -- expected " << expected_length << " but " - << "only found " << ret_length << LL_ENDL; - } -#endif - return ret_length; -} - -U32 LLXMLNode::getByteValue(U32 expected_length, U8 *array, Encoding encoding) -{ - llassert(array); - - // Check type - accept bytes or integers (below 256 only) - if (mType != TYPE_INTEGER - && mType != TYPE_UNKNOWN) - { - return 0; - } - - if (mLength > 0 && mLength != expected_length) - { - LL_WARNS() << "XMLNode::getByteValue asked for " << expected_length - << " elements, while node has " << mLength << LL_ENDL; - return 0; - } - - if (encoding == ENCODING_DEFAULT) - { - encoding = mEncoding; - } - - const char *value_string = mValue.c_str(); - - U32 i; - for (i=0; i 255 || is_negative) - { - LL_WARNS() << "getByteValue: Value outside of valid range." << LL_ENDL; - break; - } - array[i] = U8(value); - } -#if LL_DEBUG - if (i != expected_length) - { - LL_DEBUGS() << "LLXMLNode::getByteValue() failed for node named '" - << mName->mString << "' -- expected " << expected_length << " but " - << "only found " << i << LL_ENDL; - } -#endif - return i; -} - -U32 LLXMLNode::getIntValue(U32 expected_length, S32 *array, Encoding encoding) -{ - llassert(array); - - // Check type - accept bytes or integers - if (mType != TYPE_INTEGER && mType != TYPE_UNKNOWN) - { - return 0; - } - - if (mLength > 0 && mLength != expected_length) - { - LL_WARNS() << "XMLNode::getIntValue asked for " << expected_length - << " elements, while node has " << mLength << LL_ENDL; - return 0; - } - - if (encoding == ENCODING_DEFAULT) - { - encoding = mEncoding; - } - - const char *value_string = mValue.c_str(); - - U32 i = 0; - for (i=0; i 0x7fffffff) - { - LL_WARNS() << "getIntValue: Value outside of valid range." << LL_ENDL; - break; - } - array[i] = S32(value) * (is_negative?-1:1); - } - -#if LL_DEBUG - if (i != expected_length) - { - LL_DEBUGS() << "LLXMLNode::getIntValue() failed for node named '" - << mName->mString << "' -- expected " << expected_length << " but " - << "only found " << i << LL_ENDL; - } -#endif - return i; -} - -U32 LLXMLNode::getUnsignedValue(U32 expected_length, U32 *array, Encoding encoding) -{ - llassert(array); - - // Check type - accept bytes or integers - if (mType != TYPE_INTEGER && mType != TYPE_UNKNOWN) - { - return 0; - } - - if (mLength > 0 && mLength != expected_length) - { - LL_WARNS() << "XMLNode::getUnsignedValue asked for " << expected_length - << " elements, while node has " << mLength << LL_ENDL; - return 0; - } - - if (encoding == ENCODING_DEFAULT) - { - encoding = mEncoding; - } - - const char *value_string = mValue.c_str(); - - U32 i = 0; - // Int type - for (i=0; i 0xffffffff) - { - LL_WARNS() << "getUnsignedValue: Value outside of valid range." << LL_ENDL; - break; - } - array[i] = U32(value); - } - -#if LL_DEBUG - if (i != expected_length) - { - LL_DEBUGS() << "LLXMLNode::getUnsignedValue() failed for node named '" - << mName->mString << "' -- expected " << expected_length << " but " - << "only found " << i << LL_ENDL; - } -#endif - - return i; -} - -U32 LLXMLNode::getLongValue(U32 expected_length, U64 *array, Encoding encoding) -{ - llassert(array); - - // Check type - accept bytes or integers - if (mType != TYPE_INTEGER && mType != TYPE_UNKNOWN) - { - return 0; - } - - if (mLength > 0 && mLength != expected_length) - { - LL_WARNS() << "XMLNode::getLongValue asked for " << expected_length << " elements, while node has " << mLength << LL_ENDL; - return 0; - } - - if (encoding == ENCODING_DEFAULT) - { - encoding = mEncoding; - } - - const char *value_string = mValue.c_str(); - - U32 i = 0; - // Int type - for (i=0; imString << "' -- expected " << expected_length << " but " - << "only found " << i << LL_ENDL; - } -#endif - - return i; -} - -U32 LLXMLNode::getFloatValue(U32 expected_length, F32 *array, Encoding encoding) -{ - llassert(array); - - // Check type - accept only floats or doubles - if (mType != TYPE_FLOAT && mType != TYPE_UNKNOWN) - { - return 0; - } - - if (mLength > 0 && mLength != expected_length) - { - LL_WARNS() << "XMLNode::getFloatValue asked for " << expected_length << " elements, while node has " << mLength << LL_ENDL; - return 0; - } - - if (encoding == ENCODING_DEFAULT) - { - encoding = mEncoding; - } - - const char *value_string = mValue.c_str(); - - U32 i; - for (i=0; imString << "' -- expected " << expected_length << " but " - << "only found " << i << LL_ENDL; - } -#endif - return i; -} - -U32 LLXMLNode::getDoubleValue(U32 expected_length, F64 *array, Encoding encoding) -{ - llassert(array); - - // Check type - accept only floats or doubles - if (mType != TYPE_FLOAT && mType != TYPE_UNKNOWN) - { - return 0; - } - - if (mLength > 0 && mLength != expected_length) - { - LL_WARNS() << "XMLNode::getDoubleValue asked for " << expected_length << " elements, while node has " << mLength << LL_ENDL; - return 0; - } - - if (encoding == ENCODING_DEFAULT) - { - encoding = mEncoding; - } - - const char *value_string = mValue.c_str(); - - U32 i; - for (i=0; imString << "' -- expected " << expected_length << " but " - << "only found " << i << LL_ENDL; - } -#endif - return i; -} - -U32 LLXMLNode::getStringValue(U32 expected_length, std::string *array) -{ - llassert(array); - - // Can always return any value as a string - - if (mLength > 0 && mLength != expected_length) - { - LL_WARNS() << "XMLNode::getStringValue asked for " << expected_length << " elements, while node has " << mLength << LL_ENDL; - return 0; - } - - U32 num_returned_strings = 0; - - // Array of strings is whitespace-separated - const std::string sep(" \n\t"); - - std::string::size_type n = 0; - std::string::size_type m = 0; - while(1) - { - if (num_returned_strings >= expected_length) - { - break; - } - n = mValue.find_first_not_of(sep, m); - m = mValue.find_first_of(sep, n); - if (m == std::string::npos) - { - break; - } - array[num_returned_strings++] = mValue.substr(n,m-n); - } - if (n != std::string::npos && num_returned_strings < expected_length) - { - array[num_returned_strings++] = mValue.substr(n); - } -#if LL_DEBUG - if (num_returned_strings != expected_length) - { - LL_DEBUGS() << "LLXMLNode::getStringValue() failed for node named '" - << mName->mString << "' -- expected " << expected_length << " but " - << "only found " << num_returned_strings << LL_ENDL; - } -#endif - - return num_returned_strings; -} - -U32 LLXMLNode::getUUIDValue(U32 expected_length, LLUUID *array) -{ - llassert(array); - - // Check type - if (mType != TYPE_UUID && mType != TYPE_UNKNOWN) - { - return 0; - } - - const char *value_string = mValue.c_str(); - - U32 i; - for (i=0; imString << "' -- expected " << expected_length << " but " - << "only found " << i << LL_ENDL; - } -#endif - return i; -} - -U32 LLXMLNode::getNodeRefValue(U32 expected_length, LLXMLNode **array) -{ - llassert(array); - - // Check type - if (mType != TYPE_NODEREF && mType != TYPE_UNKNOWN) - { - return 0; - } - - std::string *string_array = new std::string[expected_length]; - - U32 num_strings = getStringValue(expected_length, string_array); - - U32 num_returned_refs = 0; - - LLXMLNodePtr root = getRoot(); - for (U32 strnum=0; strnumfindID(string_array[strnum], node_list); - if (node_list.empty()) - { - LL_WARNS() << "XML: Could not find node ID: " << string_array[strnum] << LL_ENDL; - } - else if (node_list.size() > 1) - { - LL_WARNS() << "XML: Node ID not unique: " << string_array[strnum] << LL_ENDL; - } - else - { - LLXMLNodeList::const_iterator list_itr = node_list.begin(); - if (list_itr != node_list.end()) - { - LLXMLNode* child = (*list_itr).second; - - array[num_returned_refs++] = child; - } - } - } - - delete[] string_array; - - return num_returned_refs; -} - -void LLXMLNode::setBoolValue(U32 length, const bool *array) -{ - if (length == 0) return; - - std::string new_value; - for (U32 pos=0; pos 0) - { - new_value = llformat("%s %s", new_value.c_str(), array[pos]?"true":"false"); - } - else - { - new_value = array[pos]?"true":"false"; - } - } - - mValue = new_value; - mEncoding = ENCODING_DEFAULT; - mLength = length; - mType = TYPE_BOOLEAN; -} - -void LLXMLNode::setByteValue(U32 length, const U8* const array, Encoding encoding) -{ - if (length == 0) return; - - std::string new_value; - if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL) - { - for (U32 pos=0; pos 0) - { - new_value.append(llformat(" %u", array[pos])); - } - else - { - new_value = llformat("%u", array[pos]); - } - } - } - if (encoding == ENCODING_HEX) - { - for (U32 pos=0; pos 0 && pos % 16 == 0) - { - new_value.append(llformat(" %02X", array[pos])); - } - else - { - new_value.append(llformat("%02X", array[pos])); - } - } - } - // TODO -- Handle Base32 - - mValue = new_value; - mEncoding = encoding; - mLength = length; - mType = TYPE_INTEGER; - mPrecision = 8; -} - - -void LLXMLNode::setIntValue(U32 length, const S32 *array, Encoding encoding) -{ - if (length == 0) return; - - std::string new_value; - if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL) - { - for (U32 pos=0; pos 0) - { - new_value.append(llformat(" %d", array[pos])); - } - else - { - new_value = llformat("%d", array[pos]); - } - } - mValue = new_value; - } - else if (encoding == ENCODING_HEX) - { - for (U32 pos=0; pos 0 && pos % 16 == 0) - { - new_value.append(llformat(" %08X", ((U32 *)array)[pos])); - } - else - { - new_value.append(llformat("%08X", ((U32 *)array)[pos])); - } - } - mValue = new_value; - } - else - { - mValue = new_value; - } - // TODO -- Handle Base32 - - mEncoding = encoding; - mLength = length; - mType = TYPE_INTEGER; - mPrecision = 32; -} - -void LLXMLNode::setUnsignedValue(U32 length, const U32* array, Encoding encoding) -{ - if (length == 0) return; - - std::string new_value; - if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL) - { - for (U32 pos=0; pos 0) - { - new_value.append(llformat(" %u", array[pos])); - } - else - { - new_value = llformat("%u", array[pos]); - } - } - } - if (encoding == ENCODING_HEX) - { - for (U32 pos=0; pos 0 && pos % 16 == 0) - { - new_value.append(llformat(" %08X", array[pos])); - } - else - { - new_value.append(llformat("%08X", array[pos])); - } - } - mValue = new_value; - } - // TODO -- Handle Base32 - - mValue = new_value; - mEncoding = encoding; - mLength = length; - mType = TYPE_INTEGER; - mPrecision = 32; -} - -#if LL_WINDOWS -#define PU64 "I64u" -#else -#define PU64 "llu" -#endif - -void LLXMLNode::setLongValue(U32 length, const U64* array, Encoding encoding) -{ - if (length == 0) return; - - std::string new_value; - if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL) - { - for (U32 pos=0; pos 0) - { - new_value.append(llformat(" %" PU64, array[pos])); - } - else - { - new_value = llformat("%" PU64, array[pos]); - } - } - mValue = new_value; - } - if (encoding == ENCODING_HEX) - { - for (U32 pos=0; pos>32); - U32 lower_32 = U32(array[pos]&0xffffffff); - if (pos > 0 && pos % 8 == 0) - { - new_value.append(llformat(" %08X%08X", upper_32, lower_32)); - } - else - { - new_value.append(llformat("%08X%08X", upper_32, lower_32)); - } - } - mValue = new_value; - } - else - { - mValue = new_value; - } - // TODO -- Handle Base32 - - mEncoding = encoding; - mLength = length; - mType = TYPE_INTEGER; - mPrecision = 64; -} - -void LLXMLNode::setFloatValue(U32 length, const F32 *array, Encoding encoding, U32 precision) -{ - if (length == 0) return; - - std::string new_value; - if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL) - { - std::string format_string; - if (precision > 0) - { - if (precision > 25) - { - precision = 25; - } - format_string = llformat( "%%.%dg", precision); - } - else - { - format_string = llformat( "%%g"); - } - - for (U32 pos=0; pos 0) - { - new_value.append(" "); - new_value.append(llformat(format_string.c_str(), array[pos])); - } - else - { - new_value.assign(llformat(format_string.c_str(), array[pos])); - } - } - mValue = new_value; - } - else if (encoding == ENCODING_HEX) - { - U32 *byte_array = (U32 *)array; - setUnsignedValue(length, byte_array, ENCODING_HEX); - } - else - { - mValue = new_value; - } - - mEncoding = encoding; - mLength = length; - mType = TYPE_FLOAT; - mPrecision = 32; -} - -void LLXMLNode::setDoubleValue(U32 length, const F64 *array, Encoding encoding, U32 precision) -{ - if (length == 0) return; - - std::string new_value; - if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL) - { - std::string format_string; - if (precision > 0) - { - if (precision > 25) - { - precision = 25; - } - format_string = llformat( "%%.%dg", precision); - } - else - { - format_string = llformat( "%%g"); - } - for (U32 pos=0; pos 0) - { - new_value.append(" "); - new_value.append(llformat(format_string.c_str(), array[pos])); - } - else - { - new_value.assign(llformat(format_string.c_str(), array[pos])); - } - } - mValue = new_value; - } - if (encoding == ENCODING_HEX) - { - U64 *byte_array = (U64 *)array; - setLongValue(length, byte_array, ENCODING_HEX); - } - else - { - mValue = new_value; - } - // TODO -- Handle Base32 - - mEncoding = encoding; - mLength = length; - mType = TYPE_FLOAT; - mPrecision = 64; -} - -// static -std::string LLXMLNode::escapeXML(const std::string& xml) -{ - std::string out; - for (std::string::size_type i = 0; i < xml.size(); ++i) - { - char c = xml[i]; - switch(c) - { - case '"': out.append("""); break; - case '\'': out.append("'"); break; - case '&': out.append("&"); break; - case '<': out.append("<"); break; - case '>': out.append(">"); break; - default: out.push_back(c); break; - } - } - return out; -} - -void LLXMLNode::setStringValue(U32 length, const std::string *strings) -{ - if (length == 0) return; - - std::string new_value; - for (U32 pos=0; posmID != "") - { - new_value.append(array[pos]->mID); - } - else - { - new_value.append("(null)"); - } - if (pos < length-1) new_value.append(" "); - } - - mValue = new_value; - mEncoding = ENCODING_DEFAULT; - mLength = length; - mType = TYPE_NODEREF; -} - -void LLXMLNode::setValue(const std::string& value) -{ - if (TYPE_CONTAINER == mType) - { - mType = TYPE_UNKNOWN; - } - mValue = value; -} - -void LLXMLNode::setDefault(LLXMLNode *default_node) -{ - mDefault = default_node; -} - -void LLXMLNode::findDefault(LLXMLNode *defaults_list) -{ - if (defaults_list) - { - LLXMLNodeList children; - defaults_list->getChildren(mName->mString, children); - - LLXMLNodeList::const_iterator children_itr; - LLXMLNodeList::const_iterator children_end = children.end(); - for (children_itr = children.begin(); children_itr != children_end; ++children_itr) - { - LLXMLNode* child = (*children_itr).second; - if (child->mVersionMajor == mVersionMajor && - child->mVersionMinor == mVersionMinor) - { - mDefault = child; - return; - } - } - } - mDefault = NULL; -} - -bool LLXMLNode::deleteChildren(const std::string& name) -{ - U32 removed_count = 0; - LLXMLNodeList node_list; - findName(name, node_list); - if (!node_list.empty()) - { - // TODO -- use multimap::find() - // TODO -- need to watch out for invalid iterators - LLXMLNodeList::iterator children_itr; - for (children_itr = node_list.begin(); children_itr != node_list.end(); ++children_itr) - { - LLXMLNode* child = (*children_itr).second; - if (deleteChild(child)) - { - removed_count++; - } - } - } - return removed_count > 0; -} - -bool LLXMLNode::deleteChildren(LLStringTableEntry* name) -{ - U32 removed_count = 0; - LLXMLNodeList node_list; - findName(name, node_list); - if (!node_list.empty()) - { - // TODO -- use multimap::find() - // TODO -- need to watch out for invalid iterators - LLXMLNodeList::iterator children_itr; - for (children_itr = node_list.begin(); children_itr != node_list.end(); ++children_itr) - { - LLXMLNode* child = (*children_itr).second; - if (deleteChild(child)) - { - removed_count++; - } - } - } - return removed_count > 0; -} - -void LLXMLNode::setAttributes(LLXMLNode::ValueType type, U32 precision, LLXMLNode::Encoding encoding, U32 length) -{ - mType = type; - mEncoding = encoding; - mPrecision = precision; - mLength = length; -} - -void LLXMLNode::setName(const std::string& name) -{ - setName(gStringTable.addStringEntry(name)); -} - -void LLXMLNode::setName(LLStringTableEntry* name) -{ - LLXMLNode* old_parent = mParent; - if (mParent) - { - // we need to remove and re-add to the parent so that - // the multimap key agrees with this node's name - mParent->removeChild(this); - } - mName = name; - if (old_parent) - { - LLXMLNodePtr this_ptr(this); - old_parent->addChild(this_ptr); - } -} - -// Unused -// void LLXMLNode::appendValue(const std::string& value) -// { -// mValue.append(value); -// } - -U32 LLXMLNode::getChildCount() const -{ - if (mChildren.notNull()) - { - return mChildren->map.size(); - } - return 0; -} - -//*************************************************** -// UNIT TESTING -//*************************************************** - -U32 get_rand(U32 max_value) -{ - U32 random_num = rand() + ((U32)rand() << 16); - return (random_num % max_value); -} - -LLXMLNode *get_rand_node(LLXMLNode *node) -{ - if (node->mChildren.notNull()) - { - U32 num_children = node->mChildren->map.size(); - if (get_rand(2) == 0) - { - while (true) - { - S32 child_num = S32(get_rand(num_children*2)) - num_children; - LLXMLChildList::iterator itor = node->mChildren->map.begin(); - while (child_num > 0) - { - --child_num; - ++itor; - } - if (!itor->second->mIsAttribute) - { - return get_rand_node(itor->second); - } - } - } - } - return node; -} - -void LLXMLNode::createUnitTest(S32 max_num_children) -{ - // Random ID - std::string rand_id; - U32 rand_id_len = get_rand(10)+5; - for (U32 pos = 0; posmID = child_id; - - // Random Length - U32 array_size = get_rand(28)+1; - - // Random Encoding - Encoding new_encoding = get_rand(2)?ENCODING_DECIMAL:ENCODING_HEX; - - // Random Type - int type = get_rand(8); - switch (type) - { - case 0: // TYPE_CONTAINER - new_child->createUnitTest(max_num_children/2); - break; - case 1: // TYPE_BOOLEAN - { - bool random_bool_values[30]; - for (U32 value=0; valuesetBoolValue(array_size, random_bool_values); - } - break; - case 2: // TYPE_INTEGER (32-bit) - { - U32 random_int_values[30]; - for (U32 value=0; valuesetUnsignedValue(array_size, random_int_values, new_encoding); - } - break; - case 3: // TYPE_INTEGER (64-bit) - { - U64 random_int_values[30]; - for (U64 value=0; valuesetLongValue(array_size, random_int_values, new_encoding); - } - break; - case 4: // TYPE_FLOAT (32-bit) - { - F32 random_float_values[30]; - for (U32 value=0; valuesetFloatValue(array_size, random_float_values, new_encoding, 12); - } - break; - case 5: // TYPE_FLOAT (64-bit) - { - F64 random_float_values[30]; - for (U32 value=0; value> 32); - } - new_child->setDoubleValue(array_size, random_float_values, new_encoding, 12); - } - break; - case 6: // TYPE_UUID - { - LLUUID random_uuid_values[30]; - for (U32 value=0; valuesetUUIDValue(array_size, random_uuid_values); - } - break; - case 7: // TYPE_NODEREF - { - LLXMLNode *random_node_array[30]; - LLXMLNode *root = getRoot(); - for (U32 value=0; valuemName->mString; - for (U32 pos=0; possetNodeRefValue(array_size, (const LLXMLNode **)random_node_array); - } - break; - } - } - - createChild("integer_checksum", true)->setUnsignedValue(1, &integer_checksum, LLXMLNode::ENCODING_HEX); - createChild("long_checksum", true)->setLongValue(1, &long_checksum, LLXMLNode::ENCODING_HEX); - createChild("bool_true_count", true)->setUnsignedValue(1, &bool_true_count, LLXMLNode::ENCODING_HEX); - createChild("uuid_checksum", true)->setUUIDValue(1, &uuid_checksum); - createChild("noderef_checksum", true)->setUnsignedValue(1, &noderef_checksum, LLXMLNode::ENCODING_HEX); - createChild("float_checksum", true)->setUnsignedValue(1, &float_checksum, LLXMLNode::ENCODING_HEX); -} - -bool LLXMLNode::performUnitTest(std::string &error_buffer) -{ - if (mChildren.isNull()) - { - error_buffer.append(llformat("ERROR Node %s: No children found.\n", mName->mString)); - return false; - } - - // Checksums - U32 integer_checksum = 0; - U32 bool_true_count = 0; - LLUUID uuid_checksum; - U32 noderef_checksum = 0; - U32 float_checksum = 0; - U64 long_checksum = 0; - - LLXMLChildList::iterator itor; - for (itor=mChildren->map.begin(); itor!=mChildren->map.end(); ++itor) - { - LLXMLNode *node = itor->second; - if (node->mIsAttribute) - { - continue; - } - if (node->mType == TYPE_CONTAINER) - { - if (!node->performUnitTest(error_buffer)) - { - error_buffer.append(llformat("Child test failed for %s.\n", mName->mString)); - //return false; - } - continue; - } - if (node->mLength < 1 || node->mLength > 30) - { - error_buffer.append(llformat("ERROR Node %s: Invalid array length %d, child %s.\n", mName->mString, node->mLength, node->mName->mString)); - return false; - } - switch (node->mType) - { - case TYPE_CONTAINER: - case TYPE_UNKNOWN: - break; - case TYPE_BOOLEAN: - { - bool bool_array[30]; - if (node->getBoolValue(node->mLength, bool_array) < node->mLength) - { - error_buffer.append(llformat("ERROR Node %s: Could not read boolean array, child %s.\n", mName->mString, node->mName->mString)); - return false; - } - for (U32 pos=0; pos<(U32)node->mLength; ++pos) - { - if (bool_array[pos]) - { - ++bool_true_count; - } - } - } - break; - case TYPE_INTEGER: - { - if (node->mPrecision == 32) - { - U32 integer_array[30]; - if (node->getUnsignedValue(node->mLength, integer_array, node->mEncoding) < node->mLength) - { - error_buffer.append(llformat("ERROR Node %s: Could not read integer array, child %s.\n", mName->mString, node->mName->mString)); - return false; - } - for (U32 pos=0; pos<(U32)node->mLength; ++pos) - { - integer_checksum ^= integer_array[pos]; - } - } - else - { - U64 integer_array[30]; - if (node->getLongValue(node->mLength, integer_array, node->mEncoding) < node->mLength) - { - error_buffer.append(llformat("ERROR Node %s: Could not read long integer array, child %s.\n", mName->mString, node->mName->mString)); - return false; - } - for (U32 pos=0; pos<(U32)node->mLength; ++pos) - { - long_checksum ^= integer_array[pos]; - } - } - } - break; - case TYPE_FLOAT: - { - if (node->mPrecision == 32) - { - F32 float_array[30]; - if (node->getFloatValue(node->mLength, float_array, node->mEncoding) < node->mLength) - { - error_buffer.append(llformat("ERROR Node %s: Could not read float array, child %s.\n", mName->mString, node->mName->mString)); - return false; - } - for (U32 pos=0; pos<(U32)node->mLength; ++pos) - { - U32 float_bits = ((U32 *)float_array)[pos]; - float_checksum ^= (float_bits & 0xfffff000); - } - } - else - { - F64 float_array[30]; - if (node->getDoubleValue(node->mLength, float_array, node->mEncoding) < node->mLength) - { - error_buffer.append(llformat("ERROR Node %s: Could not read float array, child %s.\n", mName->mString, node->mName->mString)); - return false; - } - for (U32 pos=0; pos<(U32)node->mLength; ++pos) - { - U64 float_bits = ((U64 *)float_array)[pos]; - float_checksum ^= ((float_bits & 0xfffffff000000000ll) >> 32); - } - } - } - break; - case TYPE_STRING: - break; - case TYPE_UUID: - { - LLUUID uuid_array[30]; - if (node->getUUIDValue(node->mLength, uuid_array) < node->mLength) - { - error_buffer.append(llformat("ERROR Node %s: Could not read uuid array, child %s.\n", mName->mString, node->mName->mString)); - return false; - } - for (U32 pos=0; pos<(U32)node->mLength; ++pos) - { - for (S32 byte=0; bytegetNodeRefValue(node->mLength, node_array) < node->mLength) - { - error_buffer.append(llformat("ERROR Node %s: Could not read node ref array, child %s.\n", mName->mString, node->mName->mString)); - return false; - } - for (U32 pos=0; posmLength; ++pos) - { - const char *node_name = node_array[pos]->mName->mString; - for (U32 pos2=0; pos2getUnsignedValue(1, &node_integer_checksum, ENCODING_HEX) != 1) - { - error_buffer.append(llformat("ERROR Node %s: Integer checksum missing.\n", mName->mString)); - return false; - } - if (node_integer_checksum != integer_checksum) - { - error_buffer.append(llformat("ERROR Node %s: Integer checksum mismatch: read %X / calc %X.\n", mName->mString, node_integer_checksum, integer_checksum)); - return false; - } - } - - { - U64 node_long_checksum = 0; - if (!getAttribute("long_checksum", checksum_node, false) || - checksum_node->getLongValue(1, &node_long_checksum, ENCODING_HEX) != 1) - { - error_buffer.append(llformat("ERROR Node %s: Long Integer checksum missing.\n", mName->mString)); - return false; - } - if (node_long_checksum != long_checksum) - { - U32 *pp1 = (U32 *)&node_long_checksum; - U32 *pp2 = (U32 *)&long_checksum; - error_buffer.append(llformat("ERROR Node %s: Long Integer checksum mismatch: read %08X%08X / calc %08X%08X.\n", mName->mString, pp1[1], pp1[0], pp2[1], pp2[0])); - return false; - } - } - - { - U32 node_bool_true_count = 0; - if (!getAttribute("bool_true_count", checksum_node, false) || - checksum_node->getUnsignedValue(1, &node_bool_true_count, ENCODING_HEX) != 1) - { - error_buffer.append(llformat("ERROR Node %s: Boolean checksum missing.\n", mName->mString)); - return false; - } - if (node_bool_true_count != bool_true_count) - { - error_buffer.append(llformat("ERROR Node %s: Boolean checksum mismatch: read %X / calc %X.\n", mName->mString, node_bool_true_count, bool_true_count)); - return false; - } - } - - { - LLUUID node_uuid_checksum; - if (!getAttribute("uuid_checksum", checksum_node, false) || - checksum_node->getUUIDValue(1, &node_uuid_checksum) != 1) - { - error_buffer.append(llformat("ERROR Node %s: UUID checksum missing.\n", mName->mString)); - return false; - } - if (node_uuid_checksum != uuid_checksum) - { - error_buffer.append(llformat("ERROR Node %s: UUID checksum mismatch: read %s / calc %s.\n", mName->mString, node_uuid_checksum.asString().c_str(), uuid_checksum.asString().c_str())); - return false; - } - } - - { - U32 node_noderef_checksum = 0; - if (!getAttribute("noderef_checksum", checksum_node, false) || - checksum_node->getUnsignedValue(1, &node_noderef_checksum, ENCODING_HEX) != 1) - { - error_buffer.append(llformat("ERROR Node %s: Node Ref checksum missing.\n", mName->mString)); - return false; - } - if (node_noderef_checksum != noderef_checksum) - { - error_buffer.append(llformat("ERROR Node %s: Node Ref checksum mismatch: read %X / calc %X.\n", mName->mString, node_noderef_checksum, noderef_checksum)); - return false; - } - } - - { - U32 node_float_checksum = 0; - if (!getAttribute("float_checksum", checksum_node, false) || - checksum_node->getUnsignedValue(1, &node_float_checksum, ENCODING_HEX) != 1) - { - error_buffer.append(llformat("ERROR Node %s: Float checksum missing.\n", mName->mString)); - return false; - } - if (node_float_checksum != float_checksum) - { - error_buffer.append(llformat("ERROR Node %s: Float checksum mismatch: read %X / calc %X.\n", mName->mString, node_float_checksum, float_checksum)); - return false; - } - } - - return true; -} - -LLXMLNodePtr LLXMLNode::getFirstChild() const -{ - if (mChildren.isNull()) return NULL; - LLXMLNodePtr ret = mChildren->head; - return ret; -} - -LLXMLNodePtr LLXMLNode::getNextSibling() const -{ - LLXMLNodePtr ret = mNext; - return ret; -} - -std::string LLXMLNode::getSanitizedValue() const -{ - if (mIsAttribute) - { - return getValue() ; - } - else - { - return getTextContents(); - } -} - - -std::string LLXMLNode::getTextContents() const -{ - std::string msg; - std::string contents = mValue; - std::string::size_type n = contents.find_first_not_of(" \t\n"); - if (n != std::string::npos && contents[n] == '\"') - { - // Case 1: node has quoted text - S32 num_lines = 0; - while(1) - { - // mContents[n] == '"' - ++n; - std::string::size_type t = n; - std::string::size_type m = 0; - // fix-up escaped characters - while(1) - { - m = contents.find_first_of("\\\"", t); // find first \ or " - if ((m == std::string::npos) || (contents[m] == '\"')) - { - break; - } - contents.erase(m,1); - t = m+1; - } - if (m == std::string::npos) - { - break; - } - // mContents[m] == '"' - num_lines++; - msg += contents.substr(n,m-n) + "\n"; - n = contents.find_first_of("\"", m+1); - if (n == std::string::npos) - { - if (num_lines == 1) - { - msg.erase(msg.size()-1); // remove "\n" if only one line - } - break; - } - } - } - else - { - // Case 2: node has embedded text (beginning and trailing whitespace trimmed) - std::string::size_type start = mValue.find_first_not_of(" \t\n"); - if (start != mValue.npos) - { - std::string::size_type end = mValue.find_last_not_of(" \t\n"); - if (end != mValue.npos) - { - msg = mValue.substr(start, end+1-start); - } - else - { - msg = mValue.substr(start); - } - } - // Convert any internal CR to LF - msg = utf8str_removeCRLF(msg); - } - return msg; -} - -void LLXMLNode::setLineNumber(S32 line_number) -{ - mLineNumber = line_number; -} - -S32 LLXMLNode::getLineNumber() -{ - return mLineNumber; -} +/** + * @file llxmlnode.cpp + * @author Tom Yedwab + * @brief LLXMLNode implementation + * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include +#include + +#include "llxmlnode.h" + +#include "v3color.h" +#include "v4color.h" +#include "v4coloru.h" +#include "v3math.h" +#include "v3dmath.h" +#include "v4math.h" +#include "llquaternion.h" +#include "llstring.h" +#include "lluuid.h" +#include "lldir.h" + +// static +bool LLXMLNode::sStripEscapedStrings = true; +bool LLXMLNode::sStripWhitespaceValues = false; + +LLXMLNode::LLXMLNode() : + mID(""), + mParser(NULL), + mIsAttribute(false), + mVersionMajor(0), + mVersionMinor(0), + mLength(0), + mPrecision(64), + mType(TYPE_CONTAINER), + mEncoding(ENCODING_DEFAULT), + mLineNumber(-1), + mParent(NULL), + mChildren(NULL), + mAttributes(), + mPrev(NULL), + mNext(NULL), + mName(NULL), + mValue(""), + mDefault(NULL) +{ +} + +LLXMLNode::LLXMLNode(const char* name, bool is_attribute) : + mID(""), + mParser(NULL), + mIsAttribute(is_attribute), + mVersionMajor(0), + mVersionMinor(0), + mLength(0), + mPrecision(64), + mType(TYPE_CONTAINER), + mEncoding(ENCODING_DEFAULT), + mLineNumber(-1), + mParent(NULL), + mChildren(NULL), + mAttributes(), + mPrev(NULL), + mNext(NULL), + mValue(""), + mDefault(NULL) +{ + mName = gStringTable.addStringEntry(name); +} + +LLXMLNode::LLXMLNode(LLStringTableEntry* name, bool is_attribute) : + mID(""), + mParser(NULL), + mIsAttribute(is_attribute), + mVersionMajor(0), + mVersionMinor(0), + mLength(0), + mPrecision(64), + mType(TYPE_CONTAINER), + mEncoding(ENCODING_DEFAULT), + mLineNumber(-1), + mParent(NULL), + mChildren(NULL), + mAttributes(), + mPrev(NULL), + mNext(NULL), + mName(name), + mValue(""), + mDefault(NULL) +{ +} + +// copy constructor (except for the children) +LLXMLNode::LLXMLNode(const LLXMLNode& rhs) : + mID(rhs.mID), + mIsAttribute(rhs.mIsAttribute), + mVersionMajor(rhs.mVersionMajor), + mVersionMinor(rhs.mVersionMinor), + mLength(rhs.mLength), + mPrecision(rhs.mPrecision), + mType(rhs.mType), + mEncoding(rhs.mEncoding), + mLineNumber(0), + mParser(NULL), + mParent(NULL), + mChildren(NULL), + mAttributes(), + mPrev(NULL), + mNext(NULL), + mName(rhs.mName), + mValue(rhs.mValue), + mDefault(rhs.mDefault) +{ +} + +// returns a new copy of this node and all its children +LLXMLNodePtr LLXMLNode::deepCopy() +{ + LLXMLNodePtr newnode = LLXMLNodePtr(new LLXMLNode(*this)); + if (mChildren.notNull()) + { + 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::iterator iter = mAttributes.begin(); + iter != mAttributes.end(); ++iter) + { + LLXMLNodePtr temp_ptr_for_gcc(iter->second->deepCopy()); + newnode->addChild(temp_ptr_for_gcc); + } + + return newnode; +} + +// virtual +LLXMLNode::~LLXMLNode() +{ + // Strictly speaking none of this should be required execept 'delete mChildren'... + // Sadly, that's only true if we hadn't had reference-counted smart pointers linked + // in three different directions. This entire class is a frightening, hard-to-maintain + // mess. + if (mChildren.notNull()) + { + for (LLXMLChildList::iterator iter = mChildren->map.begin(); + iter != mChildren->map.end(); ++iter) + { + LLXMLNodePtr child = iter->second; + child->mParent = NULL; + child->mNext = NULL; + child->mPrev = NULL; + } + mChildren->map.clear(); + mChildren->head = NULL; + mChildren->tail = NULL; + mChildren = NULL; + } + for (LLXMLAttribList::iterator iter = mAttributes.begin(); + iter != mAttributes.end(); ++iter) + { + LLXMLNodePtr attr = iter->second; + attr->mParent = NULL; + attr->mNext = NULL; + attr->mPrev = NULL; + } + llassert(mParent == NULL); + mDefault = NULL; +} + +bool LLXMLNode::isNull() +{ + return (mName == NULL); +} + +// protected +bool LLXMLNode::removeChild(LLXMLNode *target_child) +{ + if (!target_child) + { + return false; + } + if (target_child->mIsAttribute) + { + LLXMLAttribList::iterator children_itr = mAttributes.find(target_child->mName); + if (children_itr != mAttributes.end()) + { + target_child->mParent = NULL; + mAttributes.erase(children_itr); + return true; + } + } + else if (mChildren.notNull()) + { + LLXMLChildList::iterator children_itr = mChildren->map.find(target_child->mName); + while (children_itr != mChildren->map.end()) + { + if (target_child == children_itr->second) + { + if (target_child == mChildren->head) + { + mChildren->head = target_child->mNext; + } + if (target_child == mChildren->tail) + { + mChildren->tail = target_child->mPrev; + } + + LLXMLNodePtr prev = target_child->mPrev; + LLXMLNodePtr next = target_child->mNext; + if (prev.notNull()) prev->mNext = next; + if (next.notNull()) next->mPrev = prev; + + target_child->mPrev = NULL; + target_child->mNext = NULL; + target_child->mParent = NULL; + mChildren->map.erase(children_itr); + if (mChildren->map.empty()) + { + mChildren = NULL; + } + return true; + } + else if (children_itr->first != target_child->mName) + { + break; + } + else + { + ++children_itr; + } + } + } + return false; +} + +void LLXMLNode::addChild(LLXMLNodePtr& new_child) +{ + if (new_child->mParent != NULL) + { + if (new_child->mParent == this) + { + return; + } + new_child->mParent->removeChild(new_child); + } + + new_child->mParent = this; + if (new_child->mIsAttribute) + { + LLXMLAttribList::iterator found_it = mAttributes.find(new_child->mName); + if (found_it != mAttributes.end()) + { + removeChild(found_it->second); + } + mAttributes.insert(std::make_pair(new_child->mName, new_child)); + } + else + { + if (mChildren.isNull()) + { + mChildren = new LLXMLChildren(); + mChildren->head = new_child; + mChildren->tail = new_child; + } + mChildren->map.insert(std::make_pair(new_child->mName, new_child)); + + if (mChildren->tail != new_child) + { + mChildren->tail->mNext = new_child; + new_child->mPrev = mChildren->tail; + mChildren->tail = new_child; + } + } + + new_child->updateDefault(); +} + +// virtual +LLXMLNodePtr LLXMLNode::createChild(const char* name, bool is_attribute) +{ + return createChild(gStringTable.addStringEntry(name), is_attribute); +} + +// virtual +LLXMLNodePtr LLXMLNode::createChild(LLStringTableEntry* name, bool is_attribute) +{ + LLXMLNodePtr ret(new LLXMLNode(name, is_attribute)); + ret->mID.clear(); + + addChild(ret); + return ret; +} + +bool LLXMLNode::deleteChild(LLXMLNode *child) +{ + if (removeChild(child)) + { + return true; + } + return false; +} + +void LLXMLNode::setParent(LLXMLNodePtr& new_parent) +{ + if (new_parent.notNull()) + { + LLXMLNodePtr this_ptr(this); + new_parent->addChild(this_ptr); + } + else + { + if (mParent != NULL) + { + LLXMLNodePtr old_parent = mParent; + mParent = NULL; + old_parent->removeChild(this); + } + } +} + + +void LLXMLNode::updateDefault() +{ + if (mParent != NULL && !mParent->mDefault.isNull()) + { + mDefault = NULL; + + // Find default value in parent's default tree + if (!mParent->mDefault.isNull()) + { + findDefault(mParent->mDefault); + } + } + + if (mChildren.notNull()) + { + LLXMLChildList::const_iterator children_itr; + LLXMLChildList::const_iterator children_end = mChildren->map.end(); + for (children_itr = mChildren->map.begin(); children_itr != children_end; ++children_itr) + { + LLXMLNodePtr child = (*children_itr).second; + child->updateDefault(); + } + } +} + +void XMLCALL StartXMLNode(void *userData, + const XML_Char *name, + const XML_Char **atts) +{ + // Create a new node + LLXMLNode *new_node_ptr = new LLXMLNode(name, false); + + LLXMLNodePtr new_node = new_node_ptr; + new_node->mID.clear(); + LLXMLNodePtr ptr_new_node = new_node; + + // Set the parent-child relationship with the current active node + LLXMLNode* parent = (LLXMLNode *)userData; + + if (NULL == parent) + { + LL_WARNS() << "parent (userData) is NULL; aborting function" << LL_ENDL; + return; + } + + new_node_ptr->mParser = parent->mParser; + new_node_ptr->setLineNumber(XML_GetCurrentLineNumber(*new_node_ptr->mParser)); + + // Set the current active node to the new node + XML_Parser *parser = parent->mParser; + XML_SetUserData(*parser, (void *)new_node_ptr); + + // Parse attributes + U32 pos = 0; + while (atts[pos] != NULL) + { + std::string attr_name = atts[pos]; + std::string attr_value = atts[pos+1]; + + // Special cases + if ('i' == attr_name[0] && "id" == attr_name) + { + new_node->mID = attr_value; + } + else if ('v' == attr_name[0] && "version" == attr_name) + { + U32 version_major = 0; + U32 version_minor = 0; + if (sscanf(attr_value.c_str(), "%d.%d", &version_major, &version_minor) > 0) + { + new_node->mVersionMajor = version_major; + new_node->mVersionMinor = version_minor; + } + } + else if (('s' == attr_name[0] && "size" == attr_name) || ('l' == attr_name[0] && "length" == attr_name)) + { + U32 length; + if (sscanf(attr_value.c_str(), "%d", &length) > 0) + { + new_node->mLength = length; + } + } + else if ('p' == attr_name[0] && "precision" == attr_name) + { + U32 precision; + if (sscanf(attr_value.c_str(), "%d", &precision) > 0) + { + new_node->mPrecision = precision; + } + } + else if ('t' == attr_name[0] && "type" == attr_name) + { + if ("boolean" == attr_value) + { + new_node->mType = LLXMLNode::TYPE_BOOLEAN; + } + else if ("integer" == attr_value) + { + new_node->mType = LLXMLNode::TYPE_INTEGER; + } + else if ("float" == attr_value) + { + new_node->mType = LLXMLNode::TYPE_FLOAT; + } + else if ("string" == attr_value) + { + new_node->mType = LLXMLNode::TYPE_STRING; + } + else if ("uuid" == attr_value) + { + new_node->mType = LLXMLNode::TYPE_UUID; + } + else if ("noderef" == attr_value) + { + new_node->mType = LLXMLNode::TYPE_NODEREF; + } + } + else if ('e' == attr_name[0] && "encoding" == attr_name) + { + if ("decimal" == attr_value) + { + new_node->mEncoding = LLXMLNode::ENCODING_DECIMAL; + } + else if ("hex" == attr_value) + { + new_node->mEncoding = LLXMLNode::ENCODING_HEX; + } + /*else if (attr_value == "base32") + { + new_node->mEncoding = LLXMLNode::ENCODING_BASE32; + }*/ + } + + // only one attribute child per description + LLXMLNodePtr attr_node; + if (!new_node->getAttribute(attr_name.c_str(), attr_node, false)) + { + attr_node = new LLXMLNode(attr_name.c_str(), true); + attr_node->setLineNumber(XML_GetCurrentLineNumber(*new_node_ptr->mParser)); + } + attr_node->setValue(attr_value); + new_node->addChild(attr_node); + + pos += 2; + } + + if (parent) + { + parent->addChild(new_node); + } +} + +void XMLCALL EndXMLNode(void *userData, + const XML_Char *name) +{ + // [FUGLY] Set the current active node to the current node's parent + LLXMLNode *node = (LLXMLNode *)userData; + XML_Parser *parser = node->mParser; + XML_SetUserData(*parser, (void *)node->mParent); + // SJB: total hack: + if (LLXMLNode::sStripWhitespaceValues) + { + std::string value = node->getValue(); + bool is_empty = true; + for (std::string::size_type s = 0; s < value.length(); s++) + { + char c = value[s]; + if (c != ' ' && c != '\t' && c != '\n') + { + is_empty = false; + break; + } + } + if (is_empty) + { + value.clear(); + node->setValue(value); + } + } +} + +void XMLCALL XMLData(void *userData, + const XML_Char *s, + int len) +{ + LLXMLNode* current_node = (LLXMLNode *)userData; + std::string value = current_node->getValue(); + if (LLXMLNode::sStripEscapedStrings) + { + if (s[0] == '\"' && s[len-1] == '\"') + { + // Special-case: Escaped string. + std::string unescaped_string; + for (S32 pos=1; possetValue(value); + return; + } + } + value.append(std::string(s, len)); + current_node->setValue(value); +} + + + +// static +bool LLXMLNode::updateNode( + LLXMLNodePtr& node, + LLXMLNodePtr& update_node) +{ + + if (!node || !update_node) + { + LL_WARNS() << "Node invalid" << LL_ENDL; + return false; + } + + //update the node value + node->mValue = update_node->mValue; + + //update all attribute values + LLXMLAttribList::const_iterator itor; + + for(itor = update_node->mAttributes.begin(); itor != update_node->mAttributes.end(); ++itor) + { + const LLStringTableEntry* attribNameEntry = (*itor).first; + LLXMLNodePtr updateAttribNode = (*itor).second; + + LLXMLNodePtr attribNode; + + node->getAttribute(attribNameEntry, attribNode, 0); + + if (attribNode) + { + attribNode->mValue = updateAttribNode->mValue; + } + } + + //update all of node's children with updateNodes children that match name + LLXMLNodePtr child = node->getFirstChild(); + LLXMLNodePtr last_child = child; + LLXMLNodePtr updateChild; + + for (updateChild = update_node->getFirstChild(); updateChild.notNull(); + updateChild = updateChild->getNextSibling()) + { + while(child.notNull()) + { + std::string nodeName; + std::string updateName; + + updateChild->getAttributeString("name", updateName); + child->getAttributeString("name", nodeName); + + + //if it's a combobox there's no name, but there is a value + if (updateName.empty()) + { + updateChild->getAttributeString("value", updateName); + child->getAttributeString("value", nodeName); + } + + if ((nodeName != "") && (updateName == nodeName)) + { + updateNode(child, updateChild); + last_child = child; + child = child->getNextSibling(); + if (child.isNull()) + { + child = node->getFirstChild(); + } + break; + } + + child = child->getNextSibling(); + if (child.isNull()) + { + child = node->getFirstChild(); + } + if (child == last_child) + { + break; + } + } + } + + return true; +} + +// static +bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXMLNode* defaults_tree) +{ + // 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); + + U8* buffer = new U8[length+1]; + size_t nread = fread(buffer, 1, length, fp); + buffer[nread] = 0; + fclose(fp); + + bool rv = parseBuffer(buffer, nread, node, defaults_tree); + delete [] buffer; + return rv; +} + +// static +bool LLXMLNode::parseBuffer( + U8* buffer, + U32 length, + LLXMLNodePtr& node, + LLXMLNode* defaults) +{ + // Init + XML_Parser my_parser = XML_ParserCreate(NULL); + XML_SetElementHandler(my_parser, StartXMLNode, EndXMLNode); + XML_SetCharacterDataHandler(my_parser, XMLData); + + // Create a root node + LLXMLNode *file_node_ptr = new LLXMLNode("XML", false); + LLXMLNodePtr file_node = file_node_ptr; + + file_node->mParser = &my_parser; + + XML_SetUserData(my_parser, (void *)file_node_ptr); + + // Do the parsing + 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)) + << " on line " << XML_GetCurrentLineNumber(my_parser) + << LL_ENDL; + } + + // Deinit + XML_ParserFree(my_parser); + + if (!file_node->mChildren || file_node->mChildren->map.size() != 1) + { + LL_WARNS() << "Parse failure - wrong number of top-level nodes xml." + << LL_ENDL; + node = NULL ; + return false; + } + + LLXMLNode *return_node = file_node->mChildren->map.begin()->second; + + return_node->setDefault(defaults); + return_node->updateDefault(); + + node = return_node; + return true; +} + +// static +bool LLXMLNode::parseStream( + std::istream& str, + LLXMLNodePtr& node, + LLXMLNode* defaults) +{ + // Init + XML_Parser my_parser = XML_ParserCreate(NULL); + XML_SetElementHandler(my_parser, StartXMLNode, EndXMLNode); + XML_SetCharacterDataHandler(my_parser, XMLData); + + // Create a root node + LLXMLNode *file_node_ptr = new LLXMLNode("XML", false); + LLXMLNodePtr file_node = file_node_ptr; + + file_node->mParser = &my_parser; + + XML_SetUserData(my_parser, (void *)file_node_ptr); + + const int BUFSIZE = 1024; + U8* buffer = new U8[BUFSIZE]; + + while(str.good()) + { + str.read((char*)buffer, BUFSIZE); + int count = (int)str.gcount(); + + if (XML_Parse(my_parser, (const char *)buffer, count, !str.good()) != XML_STATUS_OK) + { + LL_WARNS() << "Error parsing xml error code: " + << XML_ErrorString(XML_GetErrorCode(my_parser)) + << " on lne " << XML_GetCurrentLineNumber(my_parser) + << LL_ENDL; + break; + } + } + + delete [] buffer; + + // Deinit + XML_ParserFree(my_parser); + + if (!file_node->mChildren || file_node->mChildren->map.size() != 1) + { + LL_WARNS() << "Parse failure - wrong number of top-level nodes xml." + << LL_ENDL; + node = NULL; + return false; + } + + LLXMLNode *return_node = file_node->mChildren->map.begin()->second; + + return_node->setDefault(defaults); + return_node->updateDefault(); + + node = return_node; + return true; +} + + +bool LLXMLNode::isFullyDefault() +{ + if (mDefault.isNull()) + { + return false; + } + bool has_default_value = (mValue == mDefault->mValue); + bool has_default_attribute = (mIsAttribute == mDefault->mIsAttribute); + bool has_default_type = mIsAttribute || (mType == mDefault->mType); + bool has_default_encoding = mIsAttribute || (mEncoding == mDefault->mEncoding); + bool has_default_precision = mIsAttribute || (mPrecision == mDefault->mPrecision); + bool has_default_length = mIsAttribute || (mLength == mDefault->mLength); + + if (has_default_value + && has_default_type + && has_default_encoding + && has_default_precision + && has_default_length + && has_default_attribute) + { + if (mChildren.notNull()) + { + LLXMLChildList::const_iterator children_itr; + LLXMLChildList::const_iterator children_end = mChildren->map.end(); + for (children_itr = mChildren->map.begin(); children_itr != children_end; ++children_itr) + { + LLXMLNodePtr child = (*children_itr).second; + if (!child->isFullyDefault()) + { + return false; + } + } + } + return true; + } + + return false; +} + +// static +bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root, + const std::vector& paths) +{ + if (paths.empty()) return false; + + std::string filename = paths.front(); + if (filename.empty()) + { + return false; + } + + if (!LLXMLNode::parseFile(filename, root, NULL)) + { + LL_WARNS() << "Problem reading UI description file: " << filename << " " << errno << LL_ENDL; + return false; + } + + LLXMLNodePtr updateRoot; + + std::vector::const_iterator itor; + + // We've already dealt with the first item, skip that one + for (itor = paths.begin() + 1; itor != paths.end(); ++itor) + { + std::string layer_filename = *itor; + if(layer_filename.empty() || layer_filename == filename) + { + // no localized version of this file, that's ok, keep looking + continue; + } + + if (!LLXMLNode::parseFile(layer_filename, updateRoot, NULL)) + { + LL_WARNS() << "Problem reading localized UI description file: " << layer_filename << LL_ENDL; + return false; + } + + std::string nodeName; + std::string updateName; + + updateRoot->getAttributeString("name", updateName); + root->getAttributeString("name", nodeName); + + if (updateName == nodeName) + { + LLXMLNode::updateNode(root, updateRoot); + } + } + + return true; +} + +// static +void LLXMLNode::writeHeaderToFile(LLFILE *out_file) +{ + fprintf(out_file, "\n"); +} + +void LLXMLNode::writeToFile(LLFILE *out_file, const std::string& indent, bool use_type_decorations) +{ + if (isFullyDefault()) + { + // Don't write out nodes that are an exact match to defaults + return; + } + + std::ostringstream ostream; + writeToOstream(ostream, indent, use_type_decorations); + std::string outstring = ostream.str(); + size_t written = fwrite(outstring.c_str(), 1, outstring.length(), out_file); + if (written != outstring.length()) + { + LL_WARNS() << "Short write" << LL_ENDL; + } +} + +void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& indent, bool use_type_decorations) +{ + if (isFullyDefault()) + { + // Don't write out nodes that are an exact match to defaults + return; + } + + bool has_default_type = mDefault.isNull()?false:(mType == mDefault->mType); + bool has_default_encoding = mDefault.isNull()?false:(mEncoding == mDefault->mEncoding); + bool has_default_precision = mDefault.isNull()?false:(mPrecision == mDefault->mPrecision); + bool has_default_length = mDefault.isNull()?false:(mLength == mDefault->mLength); + + // stream the name + output_stream << indent << "<" << mName->mString << "\n"; + + if (use_type_decorations) + { + // ID + if (mID != "") + { + output_stream << indent << " id=\"" << mID << "\"\n"; + } + + // Type + if (!has_default_type) + { + switch (mType) + { + case TYPE_BOOLEAN: + output_stream << indent << " type=\"boolean\"\n"; + break; + case TYPE_INTEGER: + output_stream << indent << " type=\"integer\"\n"; + break; + case TYPE_FLOAT: + output_stream << indent << " type=\"float\"\n"; + break; + case TYPE_STRING: + output_stream << indent << " type=\"string\"\n"; + break; + case TYPE_UUID: + output_stream << indent << " type=\"uuid\"\n"; + break; + case TYPE_NODEREF: + output_stream << indent << " type=\"noderef\"\n"; + break; + default: + // default on switch(enum) eliminates a warning on linux + break; + }; + } + + // Encoding + if (!has_default_encoding) + { + switch (mEncoding) + { + case ENCODING_DECIMAL: + output_stream << indent << " encoding=\"decimal\"\n"; + break; + case ENCODING_HEX: + output_stream << indent << " encoding=\"hex\"\n"; + break; + /*case ENCODING_BASE32: + output_stream << indent << " encoding=\"base32\"\n"; + break;*/ + default: + // default on switch(enum) eliminates a warning on linux + break; + }; + } + + // Precision + if (!has_default_precision && (mType == TYPE_INTEGER || mType == TYPE_FLOAT)) + { + output_stream << indent << " precision=\"" << mPrecision << "\"\n"; + } + + // Version + if (mVersionMajor > 0 || mVersionMinor > 0) + { + output_stream << indent << " version=\"" << mVersionMajor << "." << mVersionMinor << "\"\n"; + } + + // Array length + if (!has_default_length && mLength > 0) + { + output_stream << indent << " length=\"" << mLength << "\"\n"; + } + } + + { + // Write out attributes + LLXMLAttribList::const_iterator attr_itr; + LLXMLAttribList::const_iterator attr_end = mAttributes.end(); + for (attr_itr = mAttributes.begin(); attr_itr != attr_end; ++attr_itr) + { + LLXMLNodePtr child = (*attr_itr).second; + if (child->mDefault.isNull() || child->mDefault->mValue != child->mValue) + { + std::string attr = child->mName->mString; + if (use_type_decorations + && (attr == "id" || + attr == "type" || + attr == "encoding" || + attr == "precision" || + attr == "version" || + attr == "length")) + { + continue; // skip built-in attributes + } + + std::string attr_str = llformat(" %s=\"%s\"", + attr.c_str(), + escapeXML(child->mValue).c_str()); + output_stream << indent << attr_str << "\n"; + } + } + } + + // erase last \n before attaching final > or /> + output_stream.seekp(-1, std::ios::cur); + + if (mChildren.isNull() && mValue == "") + { + output_stream << " />\n"; + return; + } + else + { + output_stream << ">\n"; + if (mChildren.notNull()) + { + // stream non-attributes + std::string next_indent = indent + " "; + for (LLXMLNode* child = getFirstChild(); child; child = child->getNextSibling()) + { + child->writeToOstream(output_stream, next_indent, use_type_decorations); + } + } + if (!mValue.empty()) + { + std::string contents = getTextContents(); + output_stream << indent << " " << escapeXML(contents) << "\n"; + } + output_stream << indent << "mString << ">\n"; + } +} + +void LLXMLNode::findName(const std::string& name, LLXMLNodeList &results) +{ + LLStringTableEntry* name_entry = gStringTable.checkStringEntry(name); + if (name_entry == mName) + { + results.insert(std::make_pair(this->mName->mString, this)); + return; + } + if (mChildren.notNull()) + { + LLXMLChildList::const_iterator children_itr; + LLXMLChildList::const_iterator children_end = mChildren->map.end(); + for (children_itr = mChildren->map.begin(); children_itr != children_end; ++children_itr) + { + LLXMLNodePtr child = (*children_itr).second; + child->findName(name_entry, results); + } + } +} + +void LLXMLNode::findName(LLStringTableEntry* name, LLXMLNodeList &results) +{ + if (name == mName) + { + results.insert(std::make_pair(this->mName->mString, this)); + return; + } + if (mChildren.notNull()) + { + LLXMLChildList::const_iterator children_itr; + LLXMLChildList::const_iterator children_end = mChildren->map.end(); + for (children_itr = mChildren->map.begin(); children_itr != children_end; ++children_itr) + { + LLXMLNodePtr child = (*children_itr).second; + child->findName(name, results); + } + } +} + +void LLXMLNode::findID(const std::string& id, LLXMLNodeList &results) +{ + if (id == mID) + { + results.insert(std::make_pair(this->mName->mString, this)); + return; + } + if (mChildren.notNull()) + { + LLXMLChildList::const_iterator children_itr; + LLXMLChildList::const_iterator children_end = mChildren->map.end(); + for (children_itr = mChildren->map.begin(); children_itr != children_end; ++children_itr) + { + LLXMLNodePtr child = (*children_itr).second; + child->findID(id, results); + } + } +} + +void LLXMLNode::scrubToTree(LLXMLNode *tree) +{ + if (!tree || tree->mChildren.isNull()) + { + return; + } + if (mChildren.notNull()) + { + std::vector to_delete_list; + LLXMLChildList::iterator itor = mChildren->map.begin(); + while (itor != mChildren->map.end()) + { + LLXMLNodePtr child = itor->second; + LLXMLNodePtr child_tree = NULL; + // Look for this child in the default's children + bool found = false; + LLXMLChildList::iterator itor2 = tree->mChildren->map.begin(); + while (itor2 != tree->mChildren->map.end()) + { + if (child->mName == itor2->second->mName) + { + child_tree = itor2->second; + found = true; + } + ++itor2; + } + if (!found) + { + to_delete_list.push_back(child); + } + else + { + child->scrubToTree(child_tree); + } + ++itor; + } + std::vector::iterator itor3; + for (itor3=to_delete_list.begin(); itor3!=to_delete_list.end(); ++itor3) + { + LLXMLNodePtr ptr; + (*itor3)->setParent(ptr); + } + } +} + +bool LLXMLNode::getChild(const char* name, LLXMLNodePtr& node, bool use_default_if_missing) +{ + return getChild(gStringTable.checkStringEntry(name), node, use_default_if_missing); +} + +bool LLXMLNode::getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, bool use_default_if_missing) +{ + if (mChildren.notNull()) + { + LLXMLChildList::const_iterator child_itr = mChildren->map.find(name); + if (child_itr != mChildren->map.end()) + { + node = (*child_itr).second; + return true; + } + } + if (use_default_if_missing && !mDefault.isNull()) + { + return mDefault->getChild(name, node, false); + } + node = NULL; + return false; +} + +void LLXMLNode::getChildren(const char* name, LLXMLNodeList &children, bool use_default_if_missing) const +{ + getChildren(gStringTable.checkStringEntry(name), children, use_default_if_missing); +} + +void LLXMLNode::getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, bool use_default_if_missing) const +{ + if (mChildren.notNull()) + { + LLXMLChildList::const_iterator child_itr = mChildren->map.find(name); + if (child_itr != mChildren->map.end()) + { + LLXMLChildList::const_iterator children_end = mChildren->map.end(); + while (child_itr != children_end) + { + LLXMLNodePtr child = (*child_itr).second; + if (name != child->mName) + { + break; + } + children.insert(std::make_pair(child->mName->mString, child)); + child_itr++; + } + } + } + if (children.size() == 0 && use_default_if_missing && !mDefault.isNull()) + { + mDefault->getChildren(name, children, false); + } +} + +// recursively walks the tree and returns all children at all nesting levels matching the name +void LLXMLNode::getDescendants(const LLStringTableEntry* name, LLXMLNodeList &children) const +{ + if (mChildren.notNull()) + { + for (LLXMLChildList::const_iterator child_itr = mChildren->map.begin(); + child_itr != mChildren->map.end(); ++child_itr) + { + LLXMLNodePtr child = (*child_itr).second; + if (name == child->mName) + { + children.insert(std::make_pair(child->mName->mString, child)); + } + // and check each child as well + child->getDescendants(name, children); + } + } +} + +bool LLXMLNode::getAttribute(const char* name, LLXMLNodePtr& node, bool use_default_if_missing) +{ + return getAttribute(gStringTable.checkStringEntry(name), node, use_default_if_missing); +} + +bool LLXMLNode::getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, bool use_default_if_missing) +{ + LLXMLAttribList::const_iterator child_itr = mAttributes.find(name); + if (child_itr != mAttributes.end()) + { + node = (*child_itr).second; + return true; + } + if (use_default_if_missing && !mDefault.isNull()) + { + return mDefault->getAttribute(name, node, false); + } + + return false; +} + +bool LLXMLNode::setAttributeString(const char* attr, const std::string& value) +{ + LLStringTableEntry* name = gStringTable.checkStringEntry(attr); + LLXMLAttribList::const_iterator child_itr = mAttributes.find(name); + if (child_itr != mAttributes.end()) + { + LLXMLNodePtr node = (*child_itr).second; + node->setValue(value); + return true; + } + return false; +} + +bool LLXMLNode::hasAttribute(const char* name ) +{ + LLXMLNodePtr node; + return getAttribute(name, node); +} + +bool LLXMLNode::getAttributeBOOL(const char* name, bool& value ) +{ + LLXMLNodePtr node; + return (getAttribute(name, node) && node->getBoolValue(1, &value)); +} + +bool LLXMLNode::getAttributeU8(const char* name, U8& value ) +{ + LLXMLNodePtr node; + return (getAttribute(name, node) && node->getByteValue(1, &value)); +} + +bool LLXMLNode::getAttributeS8(const char* name, S8& value ) +{ + LLXMLNodePtr node; + S32 val; + if (!(getAttribute(name, node) && node->getIntValue(1, &val))) + { + return false; + } + value = val; + return true; +} + +bool LLXMLNode::getAttributeU16(const char* name, U16& value ) +{ + LLXMLNodePtr node; + U32 val; + if (!(getAttribute(name, node) && node->getUnsignedValue(1, &val))) + { + return false; + } + value = val; + return true; +} + +bool LLXMLNode::getAttributeS16(const char* name, S16& value ) +{ + LLXMLNodePtr node; + S32 val; + if (!(getAttribute(name, node) && node->getIntValue(1, &val))) + { + return false; + } + value = val; + return true; +} + +bool LLXMLNode::getAttributeU32(const char* name, U32& value ) +{ + LLXMLNodePtr node; + return (getAttribute(name, node) && node->getUnsignedValue(1, &value)); +} + +bool LLXMLNode::getAttributeS32(const char* name, S32& value ) +{ + LLXMLNodePtr node; + return (getAttribute(name, node) && node->getIntValue(1, &value)); +} + +bool LLXMLNode::getAttributeF32(const char* name, F32& value ) +{ + LLXMLNodePtr node; + return (getAttribute(name, node) && node->getFloatValue(1, &value)); +} + +bool LLXMLNode::getAttributeF64(const char* name, F64& value ) +{ + LLXMLNodePtr node; + return (getAttribute(name, node) && node->getDoubleValue(1, &value)); +} + +bool LLXMLNode::getAttributeColor(const char* name, LLColor4& value ) +{ + LLXMLNodePtr node; + return (getAttribute(name, node) && node->getFloatValue(4, value.mV)); +} + +bool LLXMLNode::getAttributeColor4(const char* name, LLColor4& value ) +{ + LLXMLNodePtr node; + return (getAttribute(name, node) && node->getFloatValue(4, value.mV)); +} + +bool LLXMLNode::getAttributeColor4U(const char* name, LLColor4U& value ) +{ + LLXMLNodePtr node; + return (getAttribute(name, node) && node->getByteValue(4, value.mV)); +} + +bool LLXMLNode::getAttributeVector3(const char* name, LLVector3& value ) +{ + LLXMLNodePtr node; + return (getAttribute(name, node) && node->getFloatValue(3, value.mV)); +} + +bool LLXMLNode::getAttributeVector3d(const char* name, LLVector3d& value ) +{ + LLXMLNodePtr node; + return (getAttribute(name, node) && node->getDoubleValue(3, value.mdV)); +} + +bool LLXMLNode::getAttributeQuat(const char* name, LLQuaternion& value ) +{ + LLXMLNodePtr node; + return (getAttribute(name, node) && node->getFloatValue(4, value.mQ)); +} + +bool LLXMLNode::getAttributeUUID(const char* name, LLUUID& value ) +{ + LLXMLNodePtr node; + return (getAttribute(name, node) && node->getUUIDValue(1, &value)); +} + +bool LLXMLNode::getAttributeString(const char* name, std::string& value ) +{ + LLXMLNodePtr node; + if (!getAttribute(name, node)) + { + return false; + } + value = node->getValue(); + return true; +} + +LLXMLNodePtr LLXMLNode::getRoot() +{ + if (mParent == NULL) + { + return this; + } + return mParent->getRoot(); +} + +/*static */ +const char *LLXMLNode::skipWhitespace(const char *str) +{ + // skip whitespace characters + while (str[0] == ' ' || str[0] == '\t' || str[0] == '\n') ++str; + return str; +} + +/*static */ +const char *LLXMLNode::skipNonWhitespace(const char *str) +{ + // skip non-whitespace characters + while (str[0] != ' ' && str[0] != '\t' && str[0] != '\n' && str[0] != 0) ++str; + return str; +} + +/*static */ +const char *LLXMLNode::parseInteger(const char *str, U64 *dest, bool *is_negative, U32 precision, Encoding encoding) +{ + *dest = 0; + *is_negative = false; + + str = skipWhitespace(str); + + if (str[0] == 0) return NULL; + + if (encoding == ENCODING_DECIMAL || encoding == ENCODING_DEFAULT) + { + if (str[0] == '+') + { + ++str; + } + if (str[0] == '-') + { + *is_negative = true; + ++str; + } + + str = skipWhitespace(str); + + U64 ret = 0; + while (str[0] >= '0' && str[0] <= '9') + { + ret *= 10; + ret += str[0] - '0'; + ++str; + } + + if (str[0] == '.') + { + // If there is a fractional part, skip it + str = skipNonWhitespace(str); + } + + *dest = ret; + return str; + } + if (encoding == ENCODING_HEX) + { + U64 ret = 0; + str = skipWhitespace(str); + for (U32 pos=0; pos<(precision/4); ++pos) + { + ret <<= 4; + str = skipWhitespace(str); + if (str[0] >= '0' && str[0] <= '9') + { + ret += str[0] - '0'; + } + else if (str[0] >= 'a' && str[0] <= 'f') + { + ret += str[0] - 'a' + 10; + } + else if (str[0] >= 'A' && str[0] <= 'F') + { + ret += str[0] - 'A' + 10; + } + else + { + return NULL; + } + ++str; + } + + *dest = ret; + return str; + } + return NULL; +} + +// 25 elements - decimal expansions of 1/(2^n), multiplied by 10 each iteration +const U64 float_coeff_table[] = + { 5, 25, 125, 625, 3125, + 15625, 78125, 390625, 1953125, 9765625, + 48828125, 244140625, 1220703125, 6103515625LL, 30517578125LL, + 152587890625LL, 762939453125LL, 3814697265625LL, 19073486328125LL, 95367431640625LL, + 476837158203125LL, 2384185791015625LL, 11920928955078125LL, 59604644775390625LL, 298023223876953125LL }; + +// 36 elements - decimal expansions of 1/(2^n) after the last 28, truncated, no multiply each iteration +const U64 float_coeff_table_2[] = + { 149011611938476562LL,74505805969238281LL, + 37252902984619140LL, 18626451492309570LL, 9313225746154785LL, 4656612873077392LL, + 2328306436538696LL, 1164153218269348LL, 582076609134674LL, 291038304567337LL, + 145519152283668LL, 72759576141834LL, 36379788070917LL, 18189894035458LL, + 9094947017729LL, 4547473508864LL, 2273736754432LL, 1136868377216LL, + 568434188608LL, 284217094304LL, 142108547152LL, 71054273576LL, + 35527136788LL, 17763568394LL, 8881784197LL, 4440892098LL, + 2220446049LL, 1110223024LL, 555111512LL, 277555756LL, + 138777878, 69388939, 34694469, 17347234, + 8673617, 4336808, 2168404, 1084202, + 542101, 271050, 135525, 67762, + }; + +/*static */ +const char *LLXMLNode::parseFloat(const char *str, F64 *dest, U32 precision, Encoding encoding) +{ + str = skipWhitespace(str); + + if (str[0] == 0) return NULL; + + if (encoding == ENCODING_DECIMAL || encoding == ENCODING_DEFAULT) + { + str = skipWhitespace(str); + + if (memcmp(str, "inf", 3) == 0) + { + *(U64 *)dest = 0x7FF0000000000000ll; + return str + 3; + } + if (memcmp(str, "-inf", 4) == 0) + { + *(U64 *)dest = 0xFFF0000000000000ll; + return str + 4; + } + if (memcmp(str, "1.#INF", 6) == 0) + { + *(U64 *)dest = 0x7FF0000000000000ll; + return str + 6; + } + if (memcmp(str, "-1.#INF", 7) == 0) + { + *(U64 *)dest = 0xFFF0000000000000ll; + return str + 7; + } + + F64 negative = 1.0f; + if (str[0] == '+') + { + ++str; + } + if (str[0] == '-') + { + negative = -1.0f; + ++str; + } + + const char* base_str = str; + str = skipWhitespace(str); + + // Parse the integer part of the expression + U64 int_part = 0; + while (str[0] >= '0' && str[0] <= '9') + { + int_part *= 10; + int_part += U64(str[0] - '0'); + ++str; + } + + U64 f_part = 0;//, f_decimal = 1; + if (str[0] == '.') + { + ++str; + U64 remainder = 0; + U32 pos = 0; + // Parse the decimal part of the expression + while (str[0] >= '0' && str[0] <= '9' && pos < 25) + { + remainder = (remainder*10) + U64(str[0] - '0'); + f_part <<= 1; + //f_decimal <<= 1; + // Check the n'th bit + if (remainder >= float_coeff_table[pos]) + { + remainder -= float_coeff_table[pos]; + f_part |= 1; + } + ++pos; + ++str; + } + if (pos == 25) + { + // Drop any excessive digits + while (str[0] >= '0' && str[0] <= '9') + { + ++str; + } + } + else + { + while (pos < 25) + { + remainder *= 10; + f_part <<= 1; + //f_decimal <<= 1; + // Check the n'th bit + if (remainder >= float_coeff_table[pos]) + { + remainder -= float_coeff_table[pos]; + f_part |= 1; + } + ++pos; + } + } + pos = 0; + while (pos < 36) + { + f_part <<= 1; + //f_decimal <<= 1; + if (remainder >= float_coeff_table_2[pos]) + { + remainder -= float_coeff_table_2[pos]; + f_part |= 1; + } + ++pos; + } + } + + F64 ret = F64(int_part) + (F64(f_part)/F64(1LL<<61)); + + F64 exponent = 1.f; + if (str[0] == 'e') + { + // Scientific notation! + ++str; + U64 exp; + bool is_negative; + str = parseInteger(str, &exp, &is_negative, 64, ENCODING_DECIMAL); + if (str == NULL) + { + exp = 1; + } + F64 exp_d = F64(exp) * (is_negative?-1:1); + exponent = pow(10.0, exp_d); + } + + if (str == base_str) + { + // no digits parsed + return NULL; + } + else + { + *dest = ret*negative*exponent; + return str; + } + } + if (encoding == ENCODING_HEX) + { + U64 bytes_dest; + bool is_negative; + str = parseInteger(str, (U64 *)&bytes_dest, &is_negative, precision, ENCODING_HEX); + // Upcast to F64 + switch (precision) + { + case 32: + { + U32 short_dest = (U32)bytes_dest; + F32 ret_val = *(F32 *)&short_dest; + *dest = ret_val; + } + break; + case 64: + *dest = *(F64 *)&bytes_dest; + break; + default: + return NULL; + } + return str; + } + return NULL; +} + +U32 LLXMLNode::getBoolValue(U32 expected_length, bool *array) +{ + llassert(array); + + // Check type - accept booleans or strings + if (mType != TYPE_BOOLEAN && mType != TYPE_STRING && mType != TYPE_UNKNOWN) + { + return 0; + } + + std::string *str_array = new std::string[expected_length]; + + U32 length = getStringValue(expected_length, str_array); + + U32 ret_length = 0; + for (U32 i=0; imString << "' -- expected " << expected_length << " but " + << "only found " << ret_length << LL_ENDL; + } +#endif + return ret_length; +} + +U32 LLXMLNode::getByteValue(U32 expected_length, U8 *array, Encoding encoding) +{ + llassert(array); + + // Check type - accept bytes or integers (below 256 only) + if (mType != TYPE_INTEGER + && mType != TYPE_UNKNOWN) + { + return 0; + } + + if (mLength > 0 && mLength != expected_length) + { + LL_WARNS() << "XMLNode::getByteValue asked for " << expected_length + << " elements, while node has " << mLength << LL_ENDL; + return 0; + } + + if (encoding == ENCODING_DEFAULT) + { + encoding = mEncoding; + } + + const char *value_string = mValue.c_str(); + + U32 i; + for (i=0; i 255 || is_negative) + { + LL_WARNS() << "getByteValue: Value outside of valid range." << LL_ENDL; + break; + } + array[i] = U8(value); + } +#if LL_DEBUG + if (i != expected_length) + { + LL_DEBUGS() << "LLXMLNode::getByteValue() failed for node named '" + << mName->mString << "' -- expected " << expected_length << " but " + << "only found " << i << LL_ENDL; + } +#endif + return i; +} + +U32 LLXMLNode::getIntValue(U32 expected_length, S32 *array, Encoding encoding) +{ + llassert(array); + + // Check type - accept bytes or integers + if (mType != TYPE_INTEGER && mType != TYPE_UNKNOWN) + { + return 0; + } + + if (mLength > 0 && mLength != expected_length) + { + LL_WARNS() << "XMLNode::getIntValue asked for " << expected_length + << " elements, while node has " << mLength << LL_ENDL; + return 0; + } + + if (encoding == ENCODING_DEFAULT) + { + encoding = mEncoding; + } + + const char *value_string = mValue.c_str(); + + U32 i = 0; + for (i=0; i 0x7fffffff) + { + LL_WARNS() << "getIntValue: Value outside of valid range." << LL_ENDL; + break; + } + array[i] = S32(value) * (is_negative?-1:1); + } + +#if LL_DEBUG + if (i != expected_length) + { + LL_DEBUGS() << "LLXMLNode::getIntValue() failed for node named '" + << mName->mString << "' -- expected " << expected_length << " but " + << "only found " << i << LL_ENDL; + } +#endif + return i; +} + +U32 LLXMLNode::getUnsignedValue(U32 expected_length, U32 *array, Encoding encoding) +{ + llassert(array); + + // Check type - accept bytes or integers + if (mType != TYPE_INTEGER && mType != TYPE_UNKNOWN) + { + return 0; + } + + if (mLength > 0 && mLength != expected_length) + { + LL_WARNS() << "XMLNode::getUnsignedValue asked for " << expected_length + << " elements, while node has " << mLength << LL_ENDL; + return 0; + } + + if (encoding == ENCODING_DEFAULT) + { + encoding = mEncoding; + } + + const char *value_string = mValue.c_str(); + + U32 i = 0; + // Int type + for (i=0; i 0xffffffff) + { + LL_WARNS() << "getUnsignedValue: Value outside of valid range." << LL_ENDL; + break; + } + array[i] = U32(value); + } + +#if LL_DEBUG + if (i != expected_length) + { + LL_DEBUGS() << "LLXMLNode::getUnsignedValue() failed for node named '" + << mName->mString << "' -- expected " << expected_length << " but " + << "only found " << i << LL_ENDL; + } +#endif + + return i; +} + +U32 LLXMLNode::getLongValue(U32 expected_length, U64 *array, Encoding encoding) +{ + llassert(array); + + // Check type - accept bytes or integers + if (mType != TYPE_INTEGER && mType != TYPE_UNKNOWN) + { + return 0; + } + + if (mLength > 0 && mLength != expected_length) + { + LL_WARNS() << "XMLNode::getLongValue asked for " << expected_length << " elements, while node has " << mLength << LL_ENDL; + return 0; + } + + if (encoding == ENCODING_DEFAULT) + { + encoding = mEncoding; + } + + const char *value_string = mValue.c_str(); + + U32 i = 0; + // Int type + for (i=0; imString << "' -- expected " << expected_length << " but " + << "only found " << i << LL_ENDL; + } +#endif + + return i; +} + +U32 LLXMLNode::getFloatValue(U32 expected_length, F32 *array, Encoding encoding) +{ + llassert(array); + + // Check type - accept only floats or doubles + if (mType != TYPE_FLOAT && mType != TYPE_UNKNOWN) + { + return 0; + } + + if (mLength > 0 && mLength != expected_length) + { + LL_WARNS() << "XMLNode::getFloatValue asked for " << expected_length << " elements, while node has " << mLength << LL_ENDL; + return 0; + } + + if (encoding == ENCODING_DEFAULT) + { + encoding = mEncoding; + } + + const char *value_string = mValue.c_str(); + + U32 i; + for (i=0; imString << "' -- expected " << expected_length << " but " + << "only found " << i << LL_ENDL; + } +#endif + return i; +} + +U32 LLXMLNode::getDoubleValue(U32 expected_length, F64 *array, Encoding encoding) +{ + llassert(array); + + // Check type - accept only floats or doubles + if (mType != TYPE_FLOAT && mType != TYPE_UNKNOWN) + { + return 0; + } + + if (mLength > 0 && mLength != expected_length) + { + LL_WARNS() << "XMLNode::getDoubleValue asked for " << expected_length << " elements, while node has " << mLength << LL_ENDL; + return 0; + } + + if (encoding == ENCODING_DEFAULT) + { + encoding = mEncoding; + } + + const char *value_string = mValue.c_str(); + + U32 i; + for (i=0; imString << "' -- expected " << expected_length << " but " + << "only found " << i << LL_ENDL; + } +#endif + return i; +} + +U32 LLXMLNode::getStringValue(U32 expected_length, std::string *array) +{ + llassert(array); + + // Can always return any value as a string + + if (mLength > 0 && mLength != expected_length) + { + LL_WARNS() << "XMLNode::getStringValue asked for " << expected_length << " elements, while node has " << mLength << LL_ENDL; + return 0; + } + + U32 num_returned_strings = 0; + + // Array of strings is whitespace-separated + const std::string sep(" \n\t"); + + std::string::size_type n = 0; + std::string::size_type m = 0; + while(1) + { + if (num_returned_strings >= expected_length) + { + break; + } + n = mValue.find_first_not_of(sep, m); + m = mValue.find_first_of(sep, n); + if (m == std::string::npos) + { + break; + } + array[num_returned_strings++] = mValue.substr(n,m-n); + } + if (n != std::string::npos && num_returned_strings < expected_length) + { + array[num_returned_strings++] = mValue.substr(n); + } +#if LL_DEBUG + if (num_returned_strings != expected_length) + { + LL_DEBUGS() << "LLXMLNode::getStringValue() failed for node named '" + << mName->mString << "' -- expected " << expected_length << " but " + << "only found " << num_returned_strings << LL_ENDL; + } +#endif + + return num_returned_strings; +} + +U32 LLXMLNode::getUUIDValue(U32 expected_length, LLUUID *array) +{ + llassert(array); + + // Check type + if (mType != TYPE_UUID && mType != TYPE_UNKNOWN) + { + return 0; + } + + const char *value_string = mValue.c_str(); + + U32 i; + for (i=0; imString << "' -- expected " << expected_length << " but " + << "only found " << i << LL_ENDL; + } +#endif + return i; +} + +U32 LLXMLNode::getNodeRefValue(U32 expected_length, LLXMLNode **array) +{ + llassert(array); + + // Check type + if (mType != TYPE_NODEREF && mType != TYPE_UNKNOWN) + { + return 0; + } + + std::string *string_array = new std::string[expected_length]; + + U32 num_strings = getStringValue(expected_length, string_array); + + U32 num_returned_refs = 0; + + LLXMLNodePtr root = getRoot(); + for (U32 strnum=0; strnumfindID(string_array[strnum], node_list); + if (node_list.empty()) + { + LL_WARNS() << "XML: Could not find node ID: " << string_array[strnum] << LL_ENDL; + } + else if (node_list.size() > 1) + { + LL_WARNS() << "XML: Node ID not unique: " << string_array[strnum] << LL_ENDL; + } + else + { + LLXMLNodeList::const_iterator list_itr = node_list.begin(); + if (list_itr != node_list.end()) + { + LLXMLNode* child = (*list_itr).second; + + array[num_returned_refs++] = child; + } + } + } + + delete[] string_array; + + return num_returned_refs; +} + +void LLXMLNode::setBoolValue(U32 length, const bool *array) +{ + if (length == 0) return; + + std::string new_value; + for (U32 pos=0; pos 0) + { + new_value = llformat("%s %s", new_value.c_str(), array[pos]?"true":"false"); + } + else + { + new_value = array[pos]?"true":"false"; + } + } + + mValue = new_value; + mEncoding = ENCODING_DEFAULT; + mLength = length; + mType = TYPE_BOOLEAN; +} + +void LLXMLNode::setByteValue(U32 length, const U8* const array, Encoding encoding) +{ + if (length == 0) return; + + std::string new_value; + if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL) + { + for (U32 pos=0; pos 0) + { + new_value.append(llformat(" %u", array[pos])); + } + else + { + new_value = llformat("%u", array[pos]); + } + } + } + if (encoding == ENCODING_HEX) + { + for (U32 pos=0; pos 0 && pos % 16 == 0) + { + new_value.append(llformat(" %02X", array[pos])); + } + else + { + new_value.append(llformat("%02X", array[pos])); + } + } + } + // TODO -- Handle Base32 + + mValue = new_value; + mEncoding = encoding; + mLength = length; + mType = TYPE_INTEGER; + mPrecision = 8; +} + + +void LLXMLNode::setIntValue(U32 length, const S32 *array, Encoding encoding) +{ + if (length == 0) return; + + std::string new_value; + if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL) + { + for (U32 pos=0; pos 0) + { + new_value.append(llformat(" %d", array[pos])); + } + else + { + new_value = llformat("%d", array[pos]); + } + } + mValue = new_value; + } + else if (encoding == ENCODING_HEX) + { + for (U32 pos=0; pos 0 && pos % 16 == 0) + { + new_value.append(llformat(" %08X", ((U32 *)array)[pos])); + } + else + { + new_value.append(llformat("%08X", ((U32 *)array)[pos])); + } + } + mValue = new_value; + } + else + { + mValue = new_value; + } + // TODO -- Handle Base32 + + mEncoding = encoding; + mLength = length; + mType = TYPE_INTEGER; + mPrecision = 32; +} + +void LLXMLNode::setUnsignedValue(U32 length, const U32* array, Encoding encoding) +{ + if (length == 0) return; + + std::string new_value; + if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL) + { + for (U32 pos=0; pos 0) + { + new_value.append(llformat(" %u", array[pos])); + } + else + { + new_value = llformat("%u", array[pos]); + } + } + } + if (encoding == ENCODING_HEX) + { + for (U32 pos=0; pos 0 && pos % 16 == 0) + { + new_value.append(llformat(" %08X", array[pos])); + } + else + { + new_value.append(llformat("%08X", array[pos])); + } + } + mValue = new_value; + } + // TODO -- Handle Base32 + + mValue = new_value; + mEncoding = encoding; + mLength = length; + mType = TYPE_INTEGER; + mPrecision = 32; +} + +#if LL_WINDOWS +#define PU64 "I64u" +#else +#define PU64 "llu" +#endif + +void LLXMLNode::setLongValue(U32 length, const U64* array, Encoding encoding) +{ + if (length == 0) return; + + std::string new_value; + if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL) + { + for (U32 pos=0; pos 0) + { + new_value.append(llformat(" %" PU64, array[pos])); + } + else + { + new_value = llformat("%" PU64, array[pos]); + } + } + mValue = new_value; + } + if (encoding == ENCODING_HEX) + { + for (U32 pos=0; pos>32); + U32 lower_32 = U32(array[pos]&0xffffffff); + if (pos > 0 && pos % 8 == 0) + { + new_value.append(llformat(" %08X%08X", upper_32, lower_32)); + } + else + { + new_value.append(llformat("%08X%08X", upper_32, lower_32)); + } + } + mValue = new_value; + } + else + { + mValue = new_value; + } + // TODO -- Handle Base32 + + mEncoding = encoding; + mLength = length; + mType = TYPE_INTEGER; + mPrecision = 64; +} + +void LLXMLNode::setFloatValue(U32 length, const F32 *array, Encoding encoding, U32 precision) +{ + if (length == 0) return; + + std::string new_value; + if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL) + { + std::string format_string; + if (precision > 0) + { + if (precision > 25) + { + precision = 25; + } + format_string = llformat( "%%.%dg", precision); + } + else + { + format_string = llformat( "%%g"); + } + + for (U32 pos=0; pos 0) + { + new_value.append(" "); + new_value.append(llformat(format_string.c_str(), array[pos])); + } + else + { + new_value.assign(llformat(format_string.c_str(), array[pos])); + } + } + mValue = new_value; + } + else if (encoding == ENCODING_HEX) + { + U32 *byte_array = (U32 *)array; + setUnsignedValue(length, byte_array, ENCODING_HEX); + } + else + { + mValue = new_value; + } + + mEncoding = encoding; + mLength = length; + mType = TYPE_FLOAT; + mPrecision = 32; +} + +void LLXMLNode::setDoubleValue(U32 length, const F64 *array, Encoding encoding, U32 precision) +{ + if (length == 0) return; + + std::string new_value; + if (encoding == ENCODING_DEFAULT || encoding == ENCODING_DECIMAL) + { + std::string format_string; + if (precision > 0) + { + if (precision > 25) + { + precision = 25; + } + format_string = llformat( "%%.%dg", precision); + } + else + { + format_string = llformat( "%%g"); + } + for (U32 pos=0; pos 0) + { + new_value.append(" "); + new_value.append(llformat(format_string.c_str(), array[pos])); + } + else + { + new_value.assign(llformat(format_string.c_str(), array[pos])); + } + } + mValue = new_value; + } + if (encoding == ENCODING_HEX) + { + U64 *byte_array = (U64 *)array; + setLongValue(length, byte_array, ENCODING_HEX); + } + else + { + mValue = new_value; + } + // TODO -- Handle Base32 + + mEncoding = encoding; + mLength = length; + mType = TYPE_FLOAT; + mPrecision = 64; +} + +// static +std::string LLXMLNode::escapeXML(const std::string& xml) +{ + std::string out; + for (std::string::size_type i = 0; i < xml.size(); ++i) + { + char c = xml[i]; + switch(c) + { + case '"': out.append("""); break; + case '\'': out.append("'"); break; + case '&': out.append("&"); break; + case '<': out.append("<"); break; + case '>': out.append(">"); break; + default: out.push_back(c); break; + } + } + return out; +} + +void LLXMLNode::setStringValue(U32 length, const std::string *strings) +{ + if (length == 0) return; + + std::string new_value; + for (U32 pos=0; posmID != "") + { + new_value.append(array[pos]->mID); + } + else + { + new_value.append("(null)"); + } + if (pos < length-1) new_value.append(" "); + } + + mValue = new_value; + mEncoding = ENCODING_DEFAULT; + mLength = length; + mType = TYPE_NODEREF; +} + +void LLXMLNode::setValue(const std::string& value) +{ + if (TYPE_CONTAINER == mType) + { + mType = TYPE_UNKNOWN; + } + mValue = value; +} + +void LLXMLNode::setDefault(LLXMLNode *default_node) +{ + mDefault = default_node; +} + +void LLXMLNode::findDefault(LLXMLNode *defaults_list) +{ + if (defaults_list) + { + LLXMLNodeList children; + defaults_list->getChildren(mName->mString, children); + + LLXMLNodeList::const_iterator children_itr; + LLXMLNodeList::const_iterator children_end = children.end(); + for (children_itr = children.begin(); children_itr != children_end; ++children_itr) + { + LLXMLNode* child = (*children_itr).second; + if (child->mVersionMajor == mVersionMajor && + child->mVersionMinor == mVersionMinor) + { + mDefault = child; + return; + } + } + } + mDefault = NULL; +} + +bool LLXMLNode::deleteChildren(const std::string& name) +{ + U32 removed_count = 0; + LLXMLNodeList node_list; + findName(name, node_list); + if (!node_list.empty()) + { + // TODO -- use multimap::find() + // TODO -- need to watch out for invalid iterators + LLXMLNodeList::iterator children_itr; + for (children_itr = node_list.begin(); children_itr != node_list.end(); ++children_itr) + { + LLXMLNode* child = (*children_itr).second; + if (deleteChild(child)) + { + removed_count++; + } + } + } + return removed_count > 0; +} + +bool LLXMLNode::deleteChildren(LLStringTableEntry* name) +{ + U32 removed_count = 0; + LLXMLNodeList node_list; + findName(name, node_list); + if (!node_list.empty()) + { + // TODO -- use multimap::find() + // TODO -- need to watch out for invalid iterators + LLXMLNodeList::iterator children_itr; + for (children_itr = node_list.begin(); children_itr != node_list.end(); ++children_itr) + { + LLXMLNode* child = (*children_itr).second; + if (deleteChild(child)) + { + removed_count++; + } + } + } + return removed_count > 0; +} + +void LLXMLNode::setAttributes(LLXMLNode::ValueType type, U32 precision, LLXMLNode::Encoding encoding, U32 length) +{ + mType = type; + mEncoding = encoding; + mPrecision = precision; + mLength = length; +} + +void LLXMLNode::setName(const std::string& name) +{ + setName(gStringTable.addStringEntry(name)); +} + +void LLXMLNode::setName(LLStringTableEntry* name) +{ + LLXMLNode* old_parent = mParent; + if (mParent) + { + // we need to remove and re-add to the parent so that + // the multimap key agrees with this node's name + mParent->removeChild(this); + } + mName = name; + if (old_parent) + { + LLXMLNodePtr this_ptr(this); + old_parent->addChild(this_ptr); + } +} + +// Unused +// void LLXMLNode::appendValue(const std::string& value) +// { +// mValue.append(value); +// } + +U32 LLXMLNode::getChildCount() const +{ + if (mChildren.notNull()) + { + return mChildren->map.size(); + } + return 0; +} + +//*************************************************** +// UNIT TESTING +//*************************************************** + +U32 get_rand(U32 max_value) +{ + U32 random_num = rand() + ((U32)rand() << 16); + return (random_num % max_value); +} + +LLXMLNode *get_rand_node(LLXMLNode *node) +{ + if (node->mChildren.notNull()) + { + U32 num_children = node->mChildren->map.size(); + if (get_rand(2) == 0) + { + while (true) + { + S32 child_num = S32(get_rand(num_children*2)) - num_children; + LLXMLChildList::iterator itor = node->mChildren->map.begin(); + while (child_num > 0) + { + --child_num; + ++itor; + } + if (!itor->second->mIsAttribute) + { + return get_rand_node(itor->second); + } + } + } + } + return node; +} + +void LLXMLNode::createUnitTest(S32 max_num_children) +{ + // Random ID + std::string rand_id; + U32 rand_id_len = get_rand(10)+5; + for (U32 pos = 0; posmID = child_id; + + // Random Length + U32 array_size = get_rand(28)+1; + + // Random Encoding + Encoding new_encoding = get_rand(2)?ENCODING_DECIMAL:ENCODING_HEX; + + // Random Type + int type = get_rand(8); + switch (type) + { + case 0: // TYPE_CONTAINER + new_child->createUnitTest(max_num_children/2); + break; + case 1: // TYPE_BOOLEAN + { + bool random_bool_values[30]; + for (U32 value=0; valuesetBoolValue(array_size, random_bool_values); + } + break; + case 2: // TYPE_INTEGER (32-bit) + { + U32 random_int_values[30]; + for (U32 value=0; valuesetUnsignedValue(array_size, random_int_values, new_encoding); + } + break; + case 3: // TYPE_INTEGER (64-bit) + { + U64 random_int_values[30]; + for (U64 value=0; valuesetLongValue(array_size, random_int_values, new_encoding); + } + break; + case 4: // TYPE_FLOAT (32-bit) + { + F32 random_float_values[30]; + for (U32 value=0; valuesetFloatValue(array_size, random_float_values, new_encoding, 12); + } + break; + case 5: // TYPE_FLOAT (64-bit) + { + F64 random_float_values[30]; + for (U32 value=0; value> 32); + } + new_child->setDoubleValue(array_size, random_float_values, new_encoding, 12); + } + break; + case 6: // TYPE_UUID + { + LLUUID random_uuid_values[30]; + for (U32 value=0; valuesetUUIDValue(array_size, random_uuid_values); + } + break; + case 7: // TYPE_NODEREF + { + LLXMLNode *random_node_array[30]; + LLXMLNode *root = getRoot(); + for (U32 value=0; valuemName->mString; + for (U32 pos=0; possetNodeRefValue(array_size, (const LLXMLNode **)random_node_array); + } + break; + } + } + + createChild("integer_checksum", true)->setUnsignedValue(1, &integer_checksum, LLXMLNode::ENCODING_HEX); + createChild("long_checksum", true)->setLongValue(1, &long_checksum, LLXMLNode::ENCODING_HEX); + createChild("bool_true_count", true)->setUnsignedValue(1, &bool_true_count, LLXMLNode::ENCODING_HEX); + createChild("uuid_checksum", true)->setUUIDValue(1, &uuid_checksum); + createChild("noderef_checksum", true)->setUnsignedValue(1, &noderef_checksum, LLXMLNode::ENCODING_HEX); + createChild("float_checksum", true)->setUnsignedValue(1, &float_checksum, LLXMLNode::ENCODING_HEX); +} + +bool LLXMLNode::performUnitTest(std::string &error_buffer) +{ + if (mChildren.isNull()) + { + error_buffer.append(llformat("ERROR Node %s: No children found.\n", mName->mString)); + return false; + } + + // Checksums + U32 integer_checksum = 0; + U32 bool_true_count = 0; + LLUUID uuid_checksum; + U32 noderef_checksum = 0; + U32 float_checksum = 0; + U64 long_checksum = 0; + + LLXMLChildList::iterator itor; + for (itor=mChildren->map.begin(); itor!=mChildren->map.end(); ++itor) + { + LLXMLNode *node = itor->second; + if (node->mIsAttribute) + { + continue; + } + if (node->mType == TYPE_CONTAINER) + { + if (!node->performUnitTest(error_buffer)) + { + error_buffer.append(llformat("Child test failed for %s.\n", mName->mString)); + //return false; + } + continue; + } + if (node->mLength < 1 || node->mLength > 30) + { + error_buffer.append(llformat("ERROR Node %s: Invalid array length %d, child %s.\n", mName->mString, node->mLength, node->mName->mString)); + return false; + } + switch (node->mType) + { + case TYPE_CONTAINER: + case TYPE_UNKNOWN: + break; + case TYPE_BOOLEAN: + { + bool bool_array[30]; + if (node->getBoolValue(node->mLength, bool_array) < node->mLength) + { + error_buffer.append(llformat("ERROR Node %s: Could not read boolean array, child %s.\n", mName->mString, node->mName->mString)); + return false; + } + for (U32 pos=0; pos<(U32)node->mLength; ++pos) + { + if (bool_array[pos]) + { + ++bool_true_count; + } + } + } + break; + case TYPE_INTEGER: + { + if (node->mPrecision == 32) + { + U32 integer_array[30]; + if (node->getUnsignedValue(node->mLength, integer_array, node->mEncoding) < node->mLength) + { + error_buffer.append(llformat("ERROR Node %s: Could not read integer array, child %s.\n", mName->mString, node->mName->mString)); + return false; + } + for (U32 pos=0; pos<(U32)node->mLength; ++pos) + { + integer_checksum ^= integer_array[pos]; + } + } + else + { + U64 integer_array[30]; + if (node->getLongValue(node->mLength, integer_array, node->mEncoding) < node->mLength) + { + error_buffer.append(llformat("ERROR Node %s: Could not read long integer array, child %s.\n", mName->mString, node->mName->mString)); + return false; + } + for (U32 pos=0; pos<(U32)node->mLength; ++pos) + { + long_checksum ^= integer_array[pos]; + } + } + } + break; + case TYPE_FLOAT: + { + if (node->mPrecision == 32) + { + F32 float_array[30]; + if (node->getFloatValue(node->mLength, float_array, node->mEncoding) < node->mLength) + { + error_buffer.append(llformat("ERROR Node %s: Could not read float array, child %s.\n", mName->mString, node->mName->mString)); + return false; + } + for (U32 pos=0; pos<(U32)node->mLength; ++pos) + { + U32 float_bits = ((U32 *)float_array)[pos]; + float_checksum ^= (float_bits & 0xfffff000); + } + } + else + { + F64 float_array[30]; + if (node->getDoubleValue(node->mLength, float_array, node->mEncoding) < node->mLength) + { + error_buffer.append(llformat("ERROR Node %s: Could not read float array, child %s.\n", mName->mString, node->mName->mString)); + return false; + } + for (U32 pos=0; pos<(U32)node->mLength; ++pos) + { + U64 float_bits = ((U64 *)float_array)[pos]; + float_checksum ^= ((float_bits & 0xfffffff000000000ll) >> 32); + } + } + } + break; + case TYPE_STRING: + break; + case TYPE_UUID: + { + LLUUID uuid_array[30]; + if (node->getUUIDValue(node->mLength, uuid_array) < node->mLength) + { + error_buffer.append(llformat("ERROR Node %s: Could not read uuid array, child %s.\n", mName->mString, node->mName->mString)); + return false; + } + for (U32 pos=0; pos<(U32)node->mLength; ++pos) + { + for (S32 byte=0; bytegetNodeRefValue(node->mLength, node_array) < node->mLength) + { + error_buffer.append(llformat("ERROR Node %s: Could not read node ref array, child %s.\n", mName->mString, node->mName->mString)); + return false; + } + for (U32 pos=0; posmLength; ++pos) + { + const char *node_name = node_array[pos]->mName->mString; + for (U32 pos2=0; pos2getUnsignedValue(1, &node_integer_checksum, ENCODING_HEX) != 1) + { + error_buffer.append(llformat("ERROR Node %s: Integer checksum missing.\n", mName->mString)); + return false; + } + if (node_integer_checksum != integer_checksum) + { + error_buffer.append(llformat("ERROR Node %s: Integer checksum mismatch: read %X / calc %X.\n", mName->mString, node_integer_checksum, integer_checksum)); + return false; + } + } + + { + U64 node_long_checksum = 0; + if (!getAttribute("long_checksum", checksum_node, false) || + checksum_node->getLongValue(1, &node_long_checksum, ENCODING_HEX) != 1) + { + error_buffer.append(llformat("ERROR Node %s: Long Integer checksum missing.\n", mName->mString)); + return false; + } + if (node_long_checksum != long_checksum) + { + U32 *pp1 = (U32 *)&node_long_checksum; + U32 *pp2 = (U32 *)&long_checksum; + error_buffer.append(llformat("ERROR Node %s: Long Integer checksum mismatch: read %08X%08X / calc %08X%08X.\n", mName->mString, pp1[1], pp1[0], pp2[1], pp2[0])); + return false; + } + } + + { + U32 node_bool_true_count = 0; + if (!getAttribute("bool_true_count", checksum_node, false) || + checksum_node->getUnsignedValue(1, &node_bool_true_count, ENCODING_HEX) != 1) + { + error_buffer.append(llformat("ERROR Node %s: Boolean checksum missing.\n", mName->mString)); + return false; + } + if (node_bool_true_count != bool_true_count) + { + error_buffer.append(llformat("ERROR Node %s: Boolean checksum mismatch: read %X / calc %X.\n", mName->mString, node_bool_true_count, bool_true_count)); + return false; + } + } + + { + LLUUID node_uuid_checksum; + if (!getAttribute("uuid_checksum", checksum_node, false) || + checksum_node->getUUIDValue(1, &node_uuid_checksum) != 1) + { + error_buffer.append(llformat("ERROR Node %s: UUID checksum missing.\n", mName->mString)); + return false; + } + if (node_uuid_checksum != uuid_checksum) + { + error_buffer.append(llformat("ERROR Node %s: UUID checksum mismatch: read %s / calc %s.\n", mName->mString, node_uuid_checksum.asString().c_str(), uuid_checksum.asString().c_str())); + return false; + } + } + + { + U32 node_noderef_checksum = 0; + if (!getAttribute("noderef_checksum", checksum_node, false) || + checksum_node->getUnsignedValue(1, &node_noderef_checksum, ENCODING_HEX) != 1) + { + error_buffer.append(llformat("ERROR Node %s: Node Ref checksum missing.\n", mName->mString)); + return false; + } + if (node_noderef_checksum != noderef_checksum) + { + error_buffer.append(llformat("ERROR Node %s: Node Ref checksum mismatch: read %X / calc %X.\n", mName->mString, node_noderef_checksum, noderef_checksum)); + return false; + } + } + + { + U32 node_float_checksum = 0; + if (!getAttribute("float_checksum", checksum_node, false) || + checksum_node->getUnsignedValue(1, &node_float_checksum, ENCODING_HEX) != 1) + { + error_buffer.append(llformat("ERROR Node %s: Float checksum missing.\n", mName->mString)); + return false; + } + if (node_float_checksum != float_checksum) + { + error_buffer.append(llformat("ERROR Node %s: Float checksum mismatch: read %X / calc %X.\n", mName->mString, node_float_checksum, float_checksum)); + return false; + } + } + + return true; +} + +LLXMLNodePtr LLXMLNode::getFirstChild() const +{ + if (mChildren.isNull()) return NULL; + LLXMLNodePtr ret = mChildren->head; + return ret; +} + +LLXMLNodePtr LLXMLNode::getNextSibling() const +{ + LLXMLNodePtr ret = mNext; + return ret; +} + +std::string LLXMLNode::getSanitizedValue() const +{ + if (mIsAttribute) + { + return getValue() ; + } + else + { + return getTextContents(); + } +} + + +std::string LLXMLNode::getTextContents() const +{ + std::string msg; + std::string contents = mValue; + std::string::size_type n = contents.find_first_not_of(" \t\n"); + if (n != std::string::npos && contents[n] == '\"') + { + // Case 1: node has quoted text + S32 num_lines = 0; + while(1) + { + // mContents[n] == '"' + ++n; + std::string::size_type t = n; + std::string::size_type m = 0; + // fix-up escaped characters + while(1) + { + m = contents.find_first_of("\\\"", t); // find first \ or " + if ((m == std::string::npos) || (contents[m] == '\"')) + { + break; + } + contents.erase(m,1); + t = m+1; + } + if (m == std::string::npos) + { + break; + } + // mContents[m] == '"' + num_lines++; + msg += contents.substr(n,m-n) + "\n"; + n = contents.find_first_of("\"", m+1); + if (n == std::string::npos) + { + if (num_lines == 1) + { + msg.erase(msg.size()-1); // remove "\n" if only one line + } + break; + } + } + } + else + { + // Case 2: node has embedded text (beginning and trailing whitespace trimmed) + std::string::size_type start = mValue.find_first_not_of(" \t\n"); + if (start != mValue.npos) + { + std::string::size_type end = mValue.find_last_not_of(" \t\n"); + if (end != mValue.npos) + { + msg = mValue.substr(start, end+1-start); + } + else + { + msg = mValue.substr(start); + } + } + // Convert any internal CR to LF + msg = utf8str_removeCRLF(msg); + } + return msg; +} + +void LLXMLNode::setLineNumber(S32 line_number) +{ + mLineNumber = line_number; +} + +S32 LLXMLNode::getLineNumber() +{ + return mLineNumber; +} diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index dd362d838a..b8e29bbfef 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -1,335 +1,335 @@ -/** - * @file llxmlnode.h - * @brief LLXMLNode definition - * - * $LicenseInfo:firstyear=2000&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLXMLNODE_H -#define LL_LLXMLNODE_H - -#ifndef XML_STATIC -#define XML_STATIC -#endif -#ifdef LL_USESYSTEMLIBS -#include -#else -#include "expat/expat.h" -#endif -#include - -#include "indra_constants.h" -#include "llrefcount.h" -#include "llpointer.h" -#include "llstring.h" -#include "llstringtable.h" -#include "llfile.h" -#include "lluuid.h" - -class LLVector3; -class LLVector3d; -class LLQuaternion; -class LLColor4; -class LLColor4U; - - -struct CompareAttributes -{ - bool operator()(const LLStringTableEntry* const lhs, const LLStringTableEntry* const rhs) const - { - if (lhs == NULL) - return true; - if (rhs == NULL) - return true; - - return strcmp(lhs->mString, rhs->mString) < 0; - } -}; - - -// Defines a simple node hierarchy for reading and writing task objects - -class LLXMLNode; -typedef LLPointer LLXMLNodePtr; -typedef std::multimap LLXMLNodeList; -typedef std::multimap LLXMLChildList; -typedef std::map LLXMLAttribList; - -class LLColor4; -class LLColor4U; -class LLQuaternion; -class LLVector3; -class LLVector3d; -class LLVector4; -class LLVector4U; - -struct LLXMLChildren : public LLThreadSafeRefCount -{ - LLXMLChildList map; // Map of children names->pointers - LLXMLNodePtr head; // Head of the double-linked list - LLXMLNodePtr tail; // Tail of the double-linked list -}; -typedef LLPointer LLXMLChildrenPtr; - -class LLXMLNode : public LLThreadSafeRefCount -{ -public: - enum ValueType - { - TYPE_CONTAINER, // A node which contains nodes - TYPE_UNKNOWN, // A node loaded from file without a specified type - TYPE_BOOLEAN, // "true" or "false" - TYPE_INTEGER, // any integer type: U8, U32, S32, U64, etc. - TYPE_FLOAT, // any floating point type: F32, F64 - TYPE_STRING, // a string - TYPE_UUID, // a UUID - TYPE_NODEREF, // the ID of another node in the hierarchy to reference - }; - - enum Encoding - { - ENCODING_DEFAULT = 0, - ENCODING_DECIMAL, - ENCODING_HEX, - // ENCODING_BASE32, // Not implemented yet - }; - -protected: - ~LLXMLNode(); - -public: - LLXMLNode(); - LLXMLNode(const char* name, bool is_attribute); - LLXMLNode(LLStringTableEntry* name, bool is_attribute); - LLXMLNode(const LLXMLNode& rhs); - LLXMLNodePtr deepCopy(); - - bool isNull(); - - bool deleteChild(LLXMLNode* child); - void addChild(LLXMLNodePtr& new_child); - void setParent(LLXMLNodePtr& new_parent); // reparent if necessary - - // Serialization - static bool parseFile( - const std::string& filename, - LLXMLNodePtr& node, - LLXMLNode* defaults_tree); - static bool parseBuffer( - U8* buffer, - U32 length, - LLXMLNodePtr& node, - LLXMLNode* defaults); - static bool parseStream( - std::istream& str, - LLXMLNodePtr& node, - LLXMLNode* defaults); - static bool updateNode( - LLXMLNodePtr& node, - LLXMLNodePtr& update_node); - - 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); - void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string(), bool use_type_decorations=true); - - // Utility - void findName(const std::string& name, LLXMLNodeList &results); - void findName(LLStringTableEntry* name, LLXMLNodeList &results); - void findID(const std::string& id, LLXMLNodeList &results); - - - virtual LLXMLNodePtr createChild(const char* name, bool is_attribute); - virtual LLXMLNodePtr createChild(LLStringTableEntry* name, bool is_attribute); - - - // Getters - U32 getBoolValue(U32 expected_length, bool *array); - U32 getByteValue(U32 expected_length, U8 *array, Encoding encoding = ENCODING_DEFAULT); - U32 getIntValue(U32 expected_length, S32 *array, Encoding encoding = ENCODING_DEFAULT); - U32 getUnsignedValue(U32 expected_length, U32 *array, Encoding encoding = ENCODING_DEFAULT); - U32 getLongValue(U32 expected_length, U64 *array, Encoding encoding = ENCODING_DEFAULT); - U32 getFloatValue(U32 expected_length, F32 *array, Encoding encoding = ENCODING_DEFAULT); - U32 getDoubleValue(U32 expected_length, F64 *array, Encoding encoding = ENCODING_DEFAULT); - U32 getStringValue(U32 expected_length, std::string *array); - U32 getUUIDValue(U32 expected_length, LLUUID *array); - U32 getNodeRefValue(U32 expected_length, LLXMLNode **array); - - bool hasAttribute(const char* name ); - - bool getAttributeBOOL(const char* name, bool& value ); - bool getAttributeU8(const char* name, U8& value ); - bool getAttributeS8(const char* name, S8& value ); - bool getAttributeU16(const char* name, U16& value ); - bool getAttributeS16(const char* name, S16& value ); - bool getAttributeU32(const char* name, U32& value ); - bool getAttributeS32(const char* name, S32& value ); - bool getAttributeF32(const char* name, F32& value ); - bool getAttributeF64(const char* name, F64& value ); - bool getAttributeColor(const char* name, LLColor4& value ); - bool getAttributeColor4(const char* name, LLColor4& value ); - bool getAttributeColor4U(const char* name, LLColor4U& value ); - bool getAttributeVector3(const char* name, LLVector3& value ); - bool getAttributeVector3d(const char* name, LLVector3d& value ); - bool getAttributeQuat(const char* name, LLQuaternion& value ); - bool getAttributeUUID(const char* name, LLUUID& value ); - bool getAttributeString(const char* name, std::string& value ); - - const ValueType& getType() const { return mType; } - U32 getLength() const { return mLength; } - U32 getPrecision() const { return mPrecision; } - const std::string& getValue() const { return mValue; } - std::string getSanitizedValue() const; - std::string getTextContents() const; - const LLStringTableEntry* getName() const { return mName; } - bool hasName(const char* name) const { return mName == gStringTable.checkStringEntry(name); } - bool hasName(const std::string& name) const { return mName == gStringTable.checkStringEntry(name.c_str()); } - const std::string& getID() const { return mID; } - - U32 getChildCount() const; - // getChild returns a Null LLXMLNode (not a NULL pointer) if there is no such child. - // This child has no value so any getTYPEValue() calls on it will return 0. - bool getChild(const char* name, LLXMLNodePtr& node, bool use_default_if_missing = true); - bool getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, bool use_default_if_missing = true); - void getChildren(const char* name, LLXMLNodeList &children, bool use_default_if_missing = true) const; - void getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, bool use_default_if_missing = true) const; - - // recursively finds all children at any level matching name - void getDescendants(const LLStringTableEntry* name, LLXMLNodeList &children) const; - - bool getAttribute(const char* name, LLXMLNodePtr& node, bool use_default_if_missing = true); - bool getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, bool use_default_if_missing = true); - - S32 getLineNumber(); - - // The following skip over attributes - LLXMLNodePtr getFirstChild() const; - LLXMLNodePtr getNextSibling() const; - - LLXMLNodePtr getRoot(); - - // 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); } - void setUnsignedValue(const U32 value, Encoding encoding = ENCODING_DEFAULT) { setUnsignedValue(1, &value, encoding); } - void setLongValue(const U64 value, Encoding encoding = ENCODING_DEFAULT) { setLongValue(1, &value, encoding); } - void setFloatValue(const F32 value, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0) { setFloatValue(1, &value, encoding); } - void setDoubleValue(const F64 value, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0) { setDoubleValue(1, &value, encoding); } - void setStringValue(const std::string& value) { setStringValue(1, &value); } - void setUUIDValue(const LLUUID value) { setUUIDValue(1, &value); } - void setNodeRefValue(const LLXMLNode *value) { setNodeRefValue(1, &value); } - - void setBoolValue(U32 length, const bool *array); - void setByteValue(U32 length, const U8 *array, Encoding encoding = ENCODING_DEFAULT); - void setIntValue(U32 length, const S32 *array, Encoding encoding = ENCODING_DEFAULT); - void setUnsignedValue(U32 length, const U32* array, Encoding encoding = ENCODING_DEFAULT); - void setLongValue(U32 length, const U64 *array, Encoding encoding = ENCODING_DEFAULT); - void setFloatValue(U32 length, const F32 *array, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0); - void setDoubleValue(U32 length, const F64 *array, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0); - void setStringValue(U32 length, const std::string *array); - void setUUIDValue(U32 length, const LLUUID *array); - void setNodeRefValue(U32 length, const LLXMLNode **array); - void setValue(const std::string& value); - void setName(const std::string& name); - void setName(LLStringTableEntry* name); - - void setLineNumber(S32 line_number); - - // Escapes " (quot) ' (apos) & (amp) < (lt) > (gt) - static std::string escapeXML(const std::string& xml); - - // Set the default node corresponding to this default node - void setDefault(LLXMLNode *default_node); - - // Find the node within defaults_list which corresponds to this node - void findDefault(LLXMLNode *defaults_list); - - void updateDefault(); - - // Delete any child nodes that aren't among the tree's children, recursive - void scrubToTree(LLXMLNode *tree); - - bool deleteChildren(const std::string& name); - bool deleteChildren(LLStringTableEntry* name); - void setAttributes(ValueType type, U32 precision, Encoding encoding, U32 length); -// void appendValue(const std::string& value); // Unused - - // Unit Testing - void createUnitTest(S32 max_num_children); - bool performUnitTest(std::string &error_buffer); - -protected: - bool removeChild(LLXMLNode* child); - -public: - std::string mID; // The ID attribute of this node - - XML_Parser *mParser; // Temporary pointer while loading - - bool mIsAttribute; // Flag is only used for output formatting - U32 mVersionMajor; // Version of this tag to use - U32 mVersionMinor; - U32 mLength; // If the length is nonzero, then only return arrays of this length - U32 mPrecision; // The number of BITS per array item - ValueType mType; // The value type - Encoding mEncoding; // The value encoding - S32 mLineNumber; // line number in source file, if applicable - - LLXMLNode* mParent; // The parent node - LLXMLChildrenPtr mChildren; // The child nodes - LLXMLAttribList mAttributes; // The attribute nodes - LLXMLNodePtr mPrev; // Double-linked list previous node - LLXMLNodePtr mNext; // Double-linked list next node - - static bool sStripEscapedStrings; - static bool sStripWhitespaceValues; - -protected: - LLStringTableEntry *mName; // The name of this node - - // The value of this node (use getters/setters only) - // Values are not XML-escaped in memory - // They may contain " (quot) ' (apos) & (amp) < (lt) > (gt) - std::string mValue; - - LLXMLNodePtr mDefault; // Mirror node in the default tree - - static const char *skipWhitespace(const char *str); - static const char *skipNonWhitespace(const char *str); - static const char *parseInteger(const char *str, U64 *dest, bool *is_negative, U32 precision, Encoding encoding); - static const char *parseFloat(const char *str, F64 *dest, U32 precision, Encoding encoding); - - bool isFullyDefault(); -}; - -#endif // LL_LLXMLNODE +/** + * @file llxmlnode.h + * @brief LLXMLNode definition + * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLXMLNODE_H +#define LL_LLXMLNODE_H + +#ifndef XML_STATIC +#define XML_STATIC +#endif +#ifdef LL_USESYSTEMLIBS +#include +#else +#include "expat/expat.h" +#endif +#include + +#include "indra_constants.h" +#include "llrefcount.h" +#include "llpointer.h" +#include "llstring.h" +#include "llstringtable.h" +#include "llfile.h" +#include "lluuid.h" + +class LLVector3; +class LLVector3d; +class LLQuaternion; +class LLColor4; +class LLColor4U; + + +struct CompareAttributes +{ + bool operator()(const LLStringTableEntry* const lhs, const LLStringTableEntry* const rhs) const + { + if (lhs == NULL) + return true; + if (rhs == NULL) + return true; + + return strcmp(lhs->mString, rhs->mString) < 0; + } +}; + + +// Defines a simple node hierarchy for reading and writing task objects + +class LLXMLNode; +typedef LLPointer LLXMLNodePtr; +typedef std::multimap LLXMLNodeList; +typedef std::multimap LLXMLChildList; +typedef std::map LLXMLAttribList; + +class LLColor4; +class LLColor4U; +class LLQuaternion; +class LLVector3; +class LLVector3d; +class LLVector4; +class LLVector4U; + +struct LLXMLChildren : public LLThreadSafeRefCount +{ + LLXMLChildList map; // Map of children names->pointers + LLXMLNodePtr head; // Head of the double-linked list + LLXMLNodePtr tail; // Tail of the double-linked list +}; +typedef LLPointer LLXMLChildrenPtr; + +class LLXMLNode : public LLThreadSafeRefCount +{ +public: + enum ValueType + { + TYPE_CONTAINER, // A node which contains nodes + TYPE_UNKNOWN, // A node loaded from file without a specified type + TYPE_BOOLEAN, // "true" or "false" + TYPE_INTEGER, // any integer type: U8, U32, S32, U64, etc. + TYPE_FLOAT, // any floating point type: F32, F64 + TYPE_STRING, // a string + TYPE_UUID, // a UUID + TYPE_NODEREF, // the ID of another node in the hierarchy to reference + }; + + enum Encoding + { + ENCODING_DEFAULT = 0, + ENCODING_DECIMAL, + ENCODING_HEX, + // ENCODING_BASE32, // Not implemented yet + }; + +protected: + ~LLXMLNode(); + +public: + LLXMLNode(); + LLXMLNode(const char* name, bool is_attribute); + LLXMLNode(LLStringTableEntry* name, bool is_attribute); + LLXMLNode(const LLXMLNode& rhs); + LLXMLNodePtr deepCopy(); + + bool isNull(); + + bool deleteChild(LLXMLNode* child); + void addChild(LLXMLNodePtr& new_child); + void setParent(LLXMLNodePtr& new_parent); // reparent if necessary + + // Serialization + static bool parseFile( + const std::string& filename, + LLXMLNodePtr& node, + LLXMLNode* defaults_tree); + static bool parseBuffer( + U8* buffer, + U32 length, + LLXMLNodePtr& node, + LLXMLNode* defaults); + static bool parseStream( + std::istream& str, + LLXMLNodePtr& node, + LLXMLNode* defaults); + static bool updateNode( + LLXMLNodePtr& node, + LLXMLNodePtr& update_node); + + 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); + void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string(), bool use_type_decorations=true); + + // Utility + void findName(const std::string& name, LLXMLNodeList &results); + void findName(LLStringTableEntry* name, LLXMLNodeList &results); + void findID(const std::string& id, LLXMLNodeList &results); + + + virtual LLXMLNodePtr createChild(const char* name, bool is_attribute); + virtual LLXMLNodePtr createChild(LLStringTableEntry* name, bool is_attribute); + + + // Getters + U32 getBoolValue(U32 expected_length, bool *array); + U32 getByteValue(U32 expected_length, U8 *array, Encoding encoding = ENCODING_DEFAULT); + U32 getIntValue(U32 expected_length, S32 *array, Encoding encoding = ENCODING_DEFAULT); + U32 getUnsignedValue(U32 expected_length, U32 *array, Encoding encoding = ENCODING_DEFAULT); + U32 getLongValue(U32 expected_length, U64 *array, Encoding encoding = ENCODING_DEFAULT); + U32 getFloatValue(U32 expected_length, F32 *array, Encoding encoding = ENCODING_DEFAULT); + U32 getDoubleValue(U32 expected_length, F64 *array, Encoding encoding = ENCODING_DEFAULT); + U32 getStringValue(U32 expected_length, std::string *array); + U32 getUUIDValue(U32 expected_length, LLUUID *array); + U32 getNodeRefValue(U32 expected_length, LLXMLNode **array); + + bool hasAttribute(const char* name ); + + bool getAttributeBOOL(const char* name, bool& value ); + bool getAttributeU8(const char* name, U8& value ); + bool getAttributeS8(const char* name, S8& value ); + bool getAttributeU16(const char* name, U16& value ); + bool getAttributeS16(const char* name, S16& value ); + bool getAttributeU32(const char* name, U32& value ); + bool getAttributeS32(const char* name, S32& value ); + bool getAttributeF32(const char* name, F32& value ); + bool getAttributeF64(const char* name, F64& value ); + bool getAttributeColor(const char* name, LLColor4& value ); + bool getAttributeColor4(const char* name, LLColor4& value ); + bool getAttributeColor4U(const char* name, LLColor4U& value ); + bool getAttributeVector3(const char* name, LLVector3& value ); + bool getAttributeVector3d(const char* name, LLVector3d& value ); + bool getAttributeQuat(const char* name, LLQuaternion& value ); + bool getAttributeUUID(const char* name, LLUUID& value ); + bool getAttributeString(const char* name, std::string& value ); + + const ValueType& getType() const { return mType; } + U32 getLength() const { return mLength; } + U32 getPrecision() const { return mPrecision; } + const std::string& getValue() const { return mValue; } + std::string getSanitizedValue() const; + std::string getTextContents() const; + const LLStringTableEntry* getName() const { return mName; } + bool hasName(const char* name) const { return mName == gStringTable.checkStringEntry(name); } + bool hasName(const std::string& name) const { return mName == gStringTable.checkStringEntry(name.c_str()); } + const std::string& getID() const { return mID; } + + U32 getChildCount() const; + // getChild returns a Null LLXMLNode (not a NULL pointer) if there is no such child. + // This child has no value so any getTYPEValue() calls on it will return 0. + bool getChild(const char* name, LLXMLNodePtr& node, bool use_default_if_missing = true); + bool getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, bool use_default_if_missing = true); + void getChildren(const char* name, LLXMLNodeList &children, bool use_default_if_missing = true) const; + void getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, bool use_default_if_missing = true) const; + + // recursively finds all children at any level matching name + void getDescendants(const LLStringTableEntry* name, LLXMLNodeList &children) const; + + bool getAttribute(const char* name, LLXMLNodePtr& node, bool use_default_if_missing = true); + bool getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, bool use_default_if_missing = true); + + S32 getLineNumber(); + + // The following skip over attributes + LLXMLNodePtr getFirstChild() const; + LLXMLNodePtr getNextSibling() const; + + LLXMLNodePtr getRoot(); + + // 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); } + void setUnsignedValue(const U32 value, Encoding encoding = ENCODING_DEFAULT) { setUnsignedValue(1, &value, encoding); } + void setLongValue(const U64 value, Encoding encoding = ENCODING_DEFAULT) { setLongValue(1, &value, encoding); } + void setFloatValue(const F32 value, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0) { setFloatValue(1, &value, encoding); } + void setDoubleValue(const F64 value, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0) { setDoubleValue(1, &value, encoding); } + void setStringValue(const std::string& value) { setStringValue(1, &value); } + void setUUIDValue(const LLUUID value) { setUUIDValue(1, &value); } + void setNodeRefValue(const LLXMLNode *value) { setNodeRefValue(1, &value); } + + void setBoolValue(U32 length, const bool *array); + void setByteValue(U32 length, const U8 *array, Encoding encoding = ENCODING_DEFAULT); + void setIntValue(U32 length, const S32 *array, Encoding encoding = ENCODING_DEFAULT); + void setUnsignedValue(U32 length, const U32* array, Encoding encoding = ENCODING_DEFAULT); + void setLongValue(U32 length, const U64 *array, Encoding encoding = ENCODING_DEFAULT); + void setFloatValue(U32 length, const F32 *array, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0); + void setDoubleValue(U32 length, const F64 *array, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0); + void setStringValue(U32 length, const std::string *array); + void setUUIDValue(U32 length, const LLUUID *array); + void setNodeRefValue(U32 length, const LLXMLNode **array); + void setValue(const std::string& value); + void setName(const std::string& name); + void setName(LLStringTableEntry* name); + + void setLineNumber(S32 line_number); + + // Escapes " (quot) ' (apos) & (amp) < (lt) > (gt) + static std::string escapeXML(const std::string& xml); + + // Set the default node corresponding to this default node + void setDefault(LLXMLNode *default_node); + + // Find the node within defaults_list which corresponds to this node + void findDefault(LLXMLNode *defaults_list); + + void updateDefault(); + + // Delete any child nodes that aren't among the tree's children, recursive + void scrubToTree(LLXMLNode *tree); + + bool deleteChildren(const std::string& name); + bool deleteChildren(LLStringTableEntry* name); + void setAttributes(ValueType type, U32 precision, Encoding encoding, U32 length); +// void appendValue(const std::string& value); // Unused + + // Unit Testing + void createUnitTest(S32 max_num_children); + bool performUnitTest(std::string &error_buffer); + +protected: + bool removeChild(LLXMLNode* child); + +public: + std::string mID; // The ID attribute of this node + + XML_Parser *mParser; // Temporary pointer while loading + + bool mIsAttribute; // Flag is only used for output formatting + U32 mVersionMajor; // Version of this tag to use + U32 mVersionMinor; + U32 mLength; // If the length is nonzero, then only return arrays of this length + U32 mPrecision; // The number of BITS per array item + ValueType mType; // The value type + Encoding mEncoding; // The value encoding + S32 mLineNumber; // line number in source file, if applicable + + LLXMLNode* mParent; // The parent node + LLXMLChildrenPtr mChildren; // The child nodes + LLXMLAttribList mAttributes; // The attribute nodes + LLXMLNodePtr mPrev; // Double-linked list previous node + LLXMLNodePtr mNext; // Double-linked list next node + + static bool sStripEscapedStrings; + static bool sStripWhitespaceValues; + +protected: + LLStringTableEntry *mName; // The name of this node + + // The value of this node (use getters/setters only) + // Values are not XML-escaped in memory + // They may contain " (quot) ' (apos) & (amp) < (lt) > (gt) + std::string mValue; + + LLXMLNodePtr mDefault; // Mirror node in the default tree + + static const char *skipWhitespace(const char *str); + static const char *skipNonWhitespace(const char *str); + static const char *parseInteger(const char *str, U64 *dest, bool *is_negative, U32 precision, Encoding encoding); + static const char *parseFloat(const char *str, F64 *dest, U32 precision, Encoding encoding); + + bool isFullyDefault(); +}; + +#endif // LL_LLXMLNODE diff --git a/indra/llxml/llxmlparser.cpp b/indra/llxml/llxmlparser.cpp index 2cae8a14a7..e2c7d17e2a 100644 --- a/indra/llxml/llxmlparser.cpp +++ b/indra/llxml/llxmlparser.cpp @@ -1,416 +1,416 @@ -/** - * @file llxmlparser.cpp - * @brief LLXmlParser implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -// llxmlparser.cpp -// -// copyright 2002, linden research inc - - -#include "linden_common.h" - -#include "llxmlparser.h" -#include "llerror.h" - - -LLXmlParser::LLXmlParser() - : - mParser( NULL ), - mDepth( 0 ) -{ - mAuxErrorString = "no error"; - - // Override the document's declared encoding. - mParser = XML_ParserCreate(NULL); - - XML_SetUserData(mParser, this); - XML_SetElementHandler( mParser, startElementHandler, endElementHandler); - XML_SetCharacterDataHandler( mParser, characterDataHandler); - XML_SetProcessingInstructionHandler( mParser, processingInstructionHandler); - XML_SetCommentHandler( mParser, commentHandler); - - XML_SetCdataSectionHandler( mParser, startCdataSectionHandler, endCdataSectionHandler); - - // This sets the default handler but does not inhibit expansion of internal entities. - // The entity reference will not be passed to the default handler. - XML_SetDefaultHandlerExpand( mParser, defaultDataHandler); - - XML_SetUnparsedEntityDeclHandler( mParser, unparsedEntityDeclHandler); -} - -LLXmlParser::~LLXmlParser() -{ - XML_ParserFree( mParser ); -} - - -bool LLXmlParser::parseFile(const std::string &path) -{ - llassert( !mDepth ); - - bool success = true; - - LLFILE* file = LLFile::fopen(path, "rb"); /* Flawfinder: ignore */ - if( !file ) - { - mAuxErrorString = llformat( "Couldn't open file %s", path.c_str()); - success = false; - } - else - { - S32 bytes_read = 0; - - fseek(file, 0L, SEEK_END); - S32 buffer_size = ftell(file); - fseek(file, 0L, SEEK_SET); - - void* buffer = XML_GetBuffer(mParser, buffer_size); - if( !buffer ) - { - mAuxErrorString = llformat( "Unable to allocate XML buffer while reading file %s", path.c_str() ); - success = false; - goto exit_label; - } - - bytes_read = (S32)fread(buffer, 1, buffer_size, file); - if( bytes_read <= 0 ) - { - mAuxErrorString = llformat( "Error while reading file %s", path.c_str() ); - success = false; - goto exit_label; - } - - if( !XML_ParseBuffer(mParser, bytes_read, true ) ) - { - mAuxErrorString = llformat( "Error while parsing file %s", path.c_str() ); - success = false; - } - -exit_label: - fclose( file ); - } - - - if( success ) - { - llassert( !mDepth ); - } - mDepth = 0; - - if( !success ) - { - LL_WARNS() << mAuxErrorString << LL_ENDL; - } - - return success; -} - - -// Parses some input. Returns 0 if a fatal error is detected. -// The last call must have isFinal true; -// len may be zero for this call (or any other). -S32 LLXmlParser::parse( const char* buf, int len, int isFinal ) -{ - return XML_Parse(mParser, buf, len, isFinal); -} - -const char* LLXmlParser::getErrorString() -{ - const char* error_string = XML_ErrorString(XML_GetErrorCode( mParser )); - if( !error_string ) - { - error_string = mAuxErrorString.c_str(); - } - return error_string; -} - -S32 LLXmlParser::getCurrentLineNumber() -{ - return XML_GetCurrentLineNumber( mParser ); -} - -S32 LLXmlParser::getCurrentColumnNumber() -{ - return XML_GetCurrentColumnNumber(mParser); -} - -/////////////////////////////////////////////////////////////////////////////// -// Pseudo-private methods. These are only used by internal callbacks. - -// static -void LLXmlParser::startElementHandler( - void *userData, - const XML_Char *name, - const XML_Char **atts) -{ - LLXmlParser* self = (LLXmlParser*) userData; - self->startElement( name, atts ); - self->mDepth++; -} - -// static -void LLXmlParser::endElementHandler( - void *userData, - const XML_Char *name) -{ - LLXmlParser* self = (LLXmlParser*) userData; - self->mDepth--; - self->endElement( name ); -} - -// s is not 0 terminated. -// static -void LLXmlParser::characterDataHandler( - void *userData, - const XML_Char *s, - int len) -{ - LLXmlParser* self = (LLXmlParser*) userData; - self->characterData( s, len ); -} - -// target and data are 0 terminated -// static -void LLXmlParser::processingInstructionHandler( - void *userData, - const XML_Char *target, - const XML_Char *data) -{ - LLXmlParser* self = (LLXmlParser*) userData; - self->processingInstruction( target, data ); -} - -// data is 0 terminated -// static -void LLXmlParser::commentHandler(void *userData, const XML_Char *data) -{ - LLXmlParser* self = (LLXmlParser*) userData; - self->comment( data ); -} - -// static -void LLXmlParser::startCdataSectionHandler(void *userData) -{ - LLXmlParser* self = (LLXmlParser*) userData; - self->mDepth++; - self->startCdataSection(); -} - -// static -void LLXmlParser::endCdataSectionHandler(void *userData) -{ - LLXmlParser* self = (LLXmlParser*) userData; - self->endCdataSection(); - self->mDepth++; -} - -// This is called for any characters in the XML document for -// which there is no applicable handler. This includes both -// characters that are part of markup which is of a kind that is -// not reported (comments, markup declarations), or characters -// that are part of a construct which could be reported but -// for which no handler has been supplied. The characters are passed -// exactly as they were in the XML document except that -// they will be encoded in UTF-8. Line boundaries are not normalized. -// Note that a byte order mark character is not passed to the default handler. -// There are no guarantees about how characters are divided between calls -// to the default handler: for example, a comment might be split between -// multiple calls. - -// static -void LLXmlParser::defaultDataHandler( - void *userData, - const XML_Char *s, - int len) -{ - LLXmlParser* self = (LLXmlParser*) userData; - self->defaultData( s, len ); -} - -// This is called for a declaration of an unparsed (NDATA) -// entity. The base argument is whatever was set by XML_SetBase. -// The entityName, systemId and notationName arguments will never be null. -// The other arguments may be. -// static -void LLXmlParser::unparsedEntityDeclHandler( - void *userData, - const XML_Char *entityName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId, - const XML_Char *notationName) -{ - LLXmlParser* self = (LLXmlParser*) userData; - self->unparsedEntityDecl( entityName, base, systemId, publicId, notationName ); -} - - - - -//////////////////////////////////////////////////////////////////// -// Test code. - -/* -class LLXmlDOMParser : public LLXmlParser -{ -public: - - LLXmlDOMParser() {} - virtual ~LLXmlDOMParser() {} - - void tabs() - { - for ( int i = 0; i < getDepth(); i++) - { - putchar(' '); - } - } - - virtual void startElement(const char *name, const char **atts) - { - tabs(); - printf("startElement %s\n", name); - - S32 i = 0; - while( atts[i] && atts[i+1] ) - { - tabs(); - printf( "\t%s=%s\n", atts[i], atts[i+1] ); - i += 2; - } - - if( atts[i] ) - { - tabs(); - printf( "\ttrailing attribute: %s\n", atts[i] ); - } - } - - virtual void endElement(const char *name) - { - tabs(); - printf("endElement %s\n", name); - } - - virtual void characterData(const char *s, int len) - { - tabs(); - - char* str = new char[len+1]; - strncpy( str, s, len ); - str[len] = '\0'; - printf("CharacterData %s\n", str); - delete str; - } - - virtual void processingInstruction(const char *target, const char *data) - { - tabs(); - printf("processingInstruction %s\n", data); - } - virtual void comment(const char *data) - { - tabs(); - printf("comment %s\n", data); - } - - virtual void startCdataSection() - { - tabs(); - printf("startCdataSection\n"); - } - - virtual void endCdataSection() - { - tabs(); - printf("endCdataSection\n"); - } - - virtual void defaultData(const char *s, int len) - { - tabs(); - - char* str = new char[len+1]; - strncpy( str, s, len ); - str[len] = '\0'; - printf("defaultData %s\n", str); - delete str; - } - - virtual void unparsedEntityDecl( - const char *entityName, - const char *base, - const char *systemId, - const char *publicId, - const char *notationName) - { - tabs(); - - printf( - "unparsed entity:\n" - "\tentityName %s\n" - "\tbase %s\n" - "\tsystemId %s\n" - "\tpublicId %s\n" - "\tnotationName %s\n", - entityName, - base, - systemId, - publicId, - notationName ); - } -}; - - -int main() -{ - char buf[1024]; - - LLFILE* file = LLFile::fopen("test.xml", "rb"); - if( !file ) - { - return 1; - } - - LLXmlDOMParser parser; - int done; - do { - size_t len = fread(buf, 1, sizeof(buf), file); - done = len < sizeof(buf); - if( 0 == parser.parse( buf, len, done) ) - { - fprintf(stderr, - "%s at line %d\n", - parser.getErrorString(), - parser.getCurrentLineNumber() ); - return 1; - } - } while (!done); - - fclose( file ); - return 0; -} -*/ - +/** + * @file llxmlparser.cpp + * @brief LLXmlParser implementation + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// llxmlparser.cpp +// +// copyright 2002, linden research inc + + +#include "linden_common.h" + +#include "llxmlparser.h" +#include "llerror.h" + + +LLXmlParser::LLXmlParser() + : + mParser( NULL ), + mDepth( 0 ) +{ + mAuxErrorString = "no error"; + + // Override the document's declared encoding. + mParser = XML_ParserCreate(NULL); + + XML_SetUserData(mParser, this); + XML_SetElementHandler( mParser, startElementHandler, endElementHandler); + XML_SetCharacterDataHandler( mParser, characterDataHandler); + XML_SetProcessingInstructionHandler( mParser, processingInstructionHandler); + XML_SetCommentHandler( mParser, commentHandler); + + XML_SetCdataSectionHandler( mParser, startCdataSectionHandler, endCdataSectionHandler); + + // This sets the default handler but does not inhibit expansion of internal entities. + // The entity reference will not be passed to the default handler. + XML_SetDefaultHandlerExpand( mParser, defaultDataHandler); + + XML_SetUnparsedEntityDeclHandler( mParser, unparsedEntityDeclHandler); +} + +LLXmlParser::~LLXmlParser() +{ + XML_ParserFree( mParser ); +} + + +bool LLXmlParser::parseFile(const std::string &path) +{ + llassert( !mDepth ); + + bool success = true; + + LLFILE* file = LLFile::fopen(path, "rb"); /* Flawfinder: ignore */ + if( !file ) + { + mAuxErrorString = llformat( "Couldn't open file %s", path.c_str()); + success = false; + } + else + { + S32 bytes_read = 0; + + fseek(file, 0L, SEEK_END); + S32 buffer_size = ftell(file); + fseek(file, 0L, SEEK_SET); + + void* buffer = XML_GetBuffer(mParser, buffer_size); + if( !buffer ) + { + mAuxErrorString = llformat( "Unable to allocate XML buffer while reading file %s", path.c_str() ); + success = false; + goto exit_label; + } + + bytes_read = (S32)fread(buffer, 1, buffer_size, file); + if( bytes_read <= 0 ) + { + mAuxErrorString = llformat( "Error while reading file %s", path.c_str() ); + success = false; + goto exit_label; + } + + if( !XML_ParseBuffer(mParser, bytes_read, true ) ) + { + mAuxErrorString = llformat( "Error while parsing file %s", path.c_str() ); + success = false; + } + +exit_label: + fclose( file ); + } + + + if( success ) + { + llassert( !mDepth ); + } + mDepth = 0; + + if( !success ) + { + LL_WARNS() << mAuxErrorString << LL_ENDL; + } + + return success; +} + + +// Parses some input. Returns 0 if a fatal error is detected. +// The last call must have isFinal true; +// len may be zero for this call (or any other). +S32 LLXmlParser::parse( const char* buf, int len, int isFinal ) +{ + return XML_Parse(mParser, buf, len, isFinal); +} + +const char* LLXmlParser::getErrorString() +{ + const char* error_string = XML_ErrorString(XML_GetErrorCode( mParser )); + if( !error_string ) + { + error_string = mAuxErrorString.c_str(); + } + return error_string; +} + +S32 LLXmlParser::getCurrentLineNumber() +{ + return XML_GetCurrentLineNumber( mParser ); +} + +S32 LLXmlParser::getCurrentColumnNumber() +{ + return XML_GetCurrentColumnNumber(mParser); +} + +/////////////////////////////////////////////////////////////////////////////// +// Pseudo-private methods. These are only used by internal callbacks. + +// static +void LLXmlParser::startElementHandler( + void *userData, + const XML_Char *name, + const XML_Char **atts) +{ + LLXmlParser* self = (LLXmlParser*) userData; + self->startElement( name, atts ); + self->mDepth++; +} + +// static +void LLXmlParser::endElementHandler( + void *userData, + const XML_Char *name) +{ + LLXmlParser* self = (LLXmlParser*) userData; + self->mDepth--; + self->endElement( name ); +} + +// s is not 0 terminated. +// static +void LLXmlParser::characterDataHandler( + void *userData, + const XML_Char *s, + int len) +{ + LLXmlParser* self = (LLXmlParser*) userData; + self->characterData( s, len ); +} + +// target and data are 0 terminated +// static +void LLXmlParser::processingInstructionHandler( + void *userData, + const XML_Char *target, + const XML_Char *data) +{ + LLXmlParser* self = (LLXmlParser*) userData; + self->processingInstruction( target, data ); +} + +// data is 0 terminated +// static +void LLXmlParser::commentHandler(void *userData, const XML_Char *data) +{ + LLXmlParser* self = (LLXmlParser*) userData; + self->comment( data ); +} + +// static +void LLXmlParser::startCdataSectionHandler(void *userData) +{ + LLXmlParser* self = (LLXmlParser*) userData; + self->mDepth++; + self->startCdataSection(); +} + +// static +void LLXmlParser::endCdataSectionHandler(void *userData) +{ + LLXmlParser* self = (LLXmlParser*) userData; + self->endCdataSection(); + self->mDepth++; +} + +// This is called for any characters in the XML document for +// which there is no applicable handler. This includes both +// characters that are part of markup which is of a kind that is +// not reported (comments, markup declarations), or characters +// that are part of a construct which could be reported but +// for which no handler has been supplied. The characters are passed +// exactly as they were in the XML document except that +// they will be encoded in UTF-8. Line boundaries are not normalized. +// Note that a byte order mark character is not passed to the default handler. +// There are no guarantees about how characters are divided between calls +// to the default handler: for example, a comment might be split between +// multiple calls. + +// static +void LLXmlParser::defaultDataHandler( + void *userData, + const XML_Char *s, + int len) +{ + LLXmlParser* self = (LLXmlParser*) userData; + self->defaultData( s, len ); +} + +// This is called for a declaration of an unparsed (NDATA) +// entity. The base argument is whatever was set by XML_SetBase. +// The entityName, systemId and notationName arguments will never be null. +// The other arguments may be. +// static +void LLXmlParser::unparsedEntityDeclHandler( + void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName) +{ + LLXmlParser* self = (LLXmlParser*) userData; + self->unparsedEntityDecl( entityName, base, systemId, publicId, notationName ); +} + + + + +//////////////////////////////////////////////////////////////////// +// Test code. + +/* +class LLXmlDOMParser : public LLXmlParser +{ +public: + + LLXmlDOMParser() {} + virtual ~LLXmlDOMParser() {} + + void tabs() + { + for ( int i = 0; i < getDepth(); i++) + { + putchar(' '); + } + } + + virtual void startElement(const char *name, const char **atts) + { + tabs(); + printf("startElement %s\n", name); + + S32 i = 0; + while( atts[i] && atts[i+1] ) + { + tabs(); + printf( "\t%s=%s\n", atts[i], atts[i+1] ); + i += 2; + } + + if( atts[i] ) + { + tabs(); + printf( "\ttrailing attribute: %s\n", atts[i] ); + } + } + + virtual void endElement(const char *name) + { + tabs(); + printf("endElement %s\n", name); + } + + virtual void characterData(const char *s, int len) + { + tabs(); + + char* str = new char[len+1]; + strncpy( str, s, len ); + str[len] = '\0'; + printf("CharacterData %s\n", str); + delete str; + } + + virtual void processingInstruction(const char *target, const char *data) + { + tabs(); + printf("processingInstruction %s\n", data); + } + virtual void comment(const char *data) + { + tabs(); + printf("comment %s\n", data); + } + + virtual void startCdataSection() + { + tabs(); + printf("startCdataSection\n"); + } + + virtual void endCdataSection() + { + tabs(); + printf("endCdataSection\n"); + } + + virtual void defaultData(const char *s, int len) + { + tabs(); + + char* str = new char[len+1]; + strncpy( str, s, len ); + str[len] = '\0'; + printf("defaultData %s\n", str); + delete str; + } + + virtual void unparsedEntityDecl( + const char *entityName, + const char *base, + const char *systemId, + const char *publicId, + const char *notationName) + { + tabs(); + + printf( + "unparsed entity:\n" + "\tentityName %s\n" + "\tbase %s\n" + "\tsystemId %s\n" + "\tpublicId %s\n" + "\tnotationName %s\n", + entityName, + base, + systemId, + publicId, + notationName ); + } +}; + + +int main() +{ + char buf[1024]; + + LLFILE* file = LLFile::fopen("test.xml", "rb"); + if( !file ) + { + return 1; + } + + LLXmlDOMParser parser; + int done; + do { + size_t len = fread(buf, 1, sizeof(buf), file); + done = len < sizeof(buf); + if( 0 == parser.parse( buf, len, done) ) + { + fprintf(stderr, + "%s at line %d\n", + parser.getErrorString(), + parser.getCurrentLineNumber() ); + return 1; + } + } while (!done); + + fclose( file ); + return 0; +} +*/ + diff --git a/indra/llxml/llxmlparser.h b/indra/llxml/llxmlparser.h index dfee4b8070..0f64def6df 100644 --- a/indra/llxml/llxmlparser.h +++ b/indra/llxml/llxmlparser.h @@ -1,133 +1,133 @@ -/** - * @file llxmlparser.h - * @brief LLXmlParser class definition - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLXMLPARSER_H -#define LL_LLXMLPARSER_H - -#ifndef XML_STATIC -#define XML_STATIC -#endif -#ifdef LL_USESYSTEMLIBS -#include -#else -#include "expat/expat.h" -#endif - -class LLXmlParser -{ -public: - LLXmlParser(); - virtual ~LLXmlParser(); - - // Parses entire file - bool parseFile(const std::string &path); - - // Parses some input. Returns 0 if a fatal error is detected. - // The last call must have isFinal true; - // len may be zero for this call (or any other). - S32 parse( const char* buf, int len, int isFinal ); - - const char* getErrorString(); - - S32 getCurrentLineNumber(); - - S32 getCurrentColumnNumber(); - - S32 getDepth() { return mDepth; } - -protected: - // atts is array of name/value pairs, terminated by 0; - // names and values are 0 terminated. - virtual void startElement(const char *name, const char **atts) {} - - virtual void endElement(const char *name) {} - - // s is not 0 terminated. - virtual void characterData(const char *s, int len) {} - - // target and data are 0 terminated - virtual void processingInstruction(const char *target, const char *data) {} - - // data is 0 terminated - virtual void comment(const char *data) {} - - virtual void startCdataSection() {} - - virtual void endCdataSection() {} - - // This is called for any characters in the XML document for - // which there is no applicable handler. This includes both - // characters that are part of markup which is of a kind that is - // not reported (comments, markup declarations), or characters - // that are part of a construct which could be reported but - // for which no handler has been supplied. The characters are passed - // exactly as they were in the XML document except that - // they will be encoded in UTF-8. Line boundaries are not normalized. - // Note that a byte order mark character is not passed to the default handler. - // There are no guarantees about how characters are divided between calls - // to the default handler: for example, a comment might be split between - // multiple calls. - virtual void defaultData(const char *s, int len) {} - - // This is called for a declaration of an unparsed (NDATA) - // entity. The base argument is whatever was set by XML_SetBase. - // The entityName, systemId and notationName arguments will never be null. - // The other arguments may be. - virtual void unparsedEntityDecl( - const char *entityName, - const char *base, - const char *systemId, - const char *publicId, - const char *notationName) {} - -public: - /////////////////////////////////////////////////////////////////////////////// - // Pseudo-private methods. These are only used by internal callbacks. - - static void startElementHandler(void *userData, const XML_Char *name, const XML_Char **atts); - static void endElementHandler(void *userData, const XML_Char *name); - static void characterDataHandler(void *userData, const XML_Char *s, int len); - static void processingInstructionHandler(void *userData, const XML_Char *target, const XML_Char *data); - static void commentHandler(void *userData, const XML_Char *data); - static void startCdataSectionHandler(void *userData); - static void endCdataSectionHandler(void *userData); - static void defaultDataHandler( void *userData, const XML_Char *s, int len); - static void unparsedEntityDeclHandler( - void *userData, - const XML_Char *entityName, - const XML_Char *base, - const XML_Char *systemId, - const XML_Char *publicId, - const XML_Char *notationName); - - -protected: - XML_Parser mParser; - int mDepth; - std::string mAuxErrorString; -}; - -#endif // LL_LLXMLPARSER_H +/** + * @file llxmlparser.h + * @brief LLXmlParser class definition + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLXMLPARSER_H +#define LL_LLXMLPARSER_H + +#ifndef XML_STATIC +#define XML_STATIC +#endif +#ifdef LL_USESYSTEMLIBS +#include +#else +#include "expat/expat.h" +#endif + +class LLXmlParser +{ +public: + LLXmlParser(); + virtual ~LLXmlParser(); + + // Parses entire file + bool parseFile(const std::string &path); + + // Parses some input. Returns 0 if a fatal error is detected. + // The last call must have isFinal true; + // len may be zero for this call (or any other). + S32 parse( const char* buf, int len, int isFinal ); + + const char* getErrorString(); + + S32 getCurrentLineNumber(); + + S32 getCurrentColumnNumber(); + + S32 getDepth() { return mDepth; } + +protected: + // atts is array of name/value pairs, terminated by 0; + // names and values are 0 terminated. + virtual void startElement(const char *name, const char **atts) {} + + virtual void endElement(const char *name) {} + + // s is not 0 terminated. + virtual void characterData(const char *s, int len) {} + + // target and data are 0 terminated + virtual void processingInstruction(const char *target, const char *data) {} + + // data is 0 terminated + virtual void comment(const char *data) {} + + virtual void startCdataSection() {} + + virtual void endCdataSection() {} + + // This is called for any characters in the XML document for + // which there is no applicable handler. This includes both + // characters that are part of markup which is of a kind that is + // not reported (comments, markup declarations), or characters + // that are part of a construct which could be reported but + // for which no handler has been supplied. The characters are passed + // exactly as they were in the XML document except that + // they will be encoded in UTF-8. Line boundaries are not normalized. + // Note that a byte order mark character is not passed to the default handler. + // There are no guarantees about how characters are divided between calls + // to the default handler: for example, a comment might be split between + // multiple calls. + virtual void defaultData(const char *s, int len) {} + + // This is called for a declaration of an unparsed (NDATA) + // entity. The base argument is whatever was set by XML_SetBase. + // The entityName, systemId and notationName arguments will never be null. + // The other arguments may be. + virtual void unparsedEntityDecl( + const char *entityName, + const char *base, + const char *systemId, + const char *publicId, + const char *notationName) {} + +public: + /////////////////////////////////////////////////////////////////////////////// + // Pseudo-private methods. These are only used by internal callbacks. + + static void startElementHandler(void *userData, const XML_Char *name, const XML_Char **atts); + static void endElementHandler(void *userData, const XML_Char *name); + static void characterDataHandler(void *userData, const XML_Char *s, int len); + static void processingInstructionHandler(void *userData, const XML_Char *target, const XML_Char *data); + static void commentHandler(void *userData, const XML_Char *data); + static void startCdataSectionHandler(void *userData); + static void endCdataSectionHandler(void *userData); + static void defaultDataHandler( void *userData, const XML_Char *s, int len); + static void unparsedEntityDeclHandler( + void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + + +protected: + XML_Parser mParser; + int mDepth; + std::string mAuxErrorString; +}; + +#endif // LL_LLXMLPARSER_H diff --git a/indra/llxml/llxmltree.cpp b/indra/llxml/llxmltree.cpp index 626bbcabc3..0ace1baf2a 100644 --- a/indra/llxml/llxmltree.cpp +++ b/indra/llxml/llxmltree.cpp @@ -1,694 +1,694 @@ -/** - * @file llxmltree.cpp - * @brief LLXmlTree implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "llxmltree.h" -#include "v3color.h" -#include "v4color.h" -#include "v4coloru.h" -#include "v3math.h" -#include "v3dmath.h" -#include "v4math.h" -#include "llquaternion.h" -#include "lluuid.h" - -////////////////////////////////////////////////////////////// -// LLXmlTree - -// static -LLStdStringTable LLXmlTree::sAttributeKeys(1024); - -LLXmlTree::LLXmlTree() - : mRoot( NULL ), - mNodeNames(512) -{ -} - -LLXmlTree::~LLXmlTree() -{ - cleanup(); -} - -void LLXmlTree::cleanup() -{ - delete mRoot; - mRoot = NULL; - mNodeNames.cleanup(); -} - - -bool LLXmlTree::parseFile(const std::string &path, bool keep_contents) -{ - delete mRoot; - mRoot = NULL; - - LLXmlTreeParser parser(this); - 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; -} - -void LLXmlTree::dump() -{ - if( mRoot ) - { - dumpNode( mRoot, " " ); - } -} - -void LLXmlTree::dumpNode( LLXmlTreeNode* node, const std::string& prefix ) -{ - node->dump( prefix ); - - std::string new_prefix = prefix + " "; - for( LLXmlTreeNode* child = node->getFirstChild(); child; child = node->getNextChild() ) - { - dumpNode( child, new_prefix ); - } -} - -////////////////////////////////////////////////////////////// -// LLXmlTreeNode - -LLXmlTreeNode::LLXmlTreeNode( const std::string& name, LLXmlTreeNode* parent, LLXmlTree* tree ) - : mName(name), - mParent(parent), - mTree(tree) -{ -} - -LLXmlTreeNode::~LLXmlTreeNode() -{ - attribute_map_t::iterator iter; - for (iter=mAttributes.begin(); iter != mAttributes.end(); iter++) - delete iter->second; - for(LLXmlTreeNode* node : mChildren) - { - delete node; - } - mChildren.clear(); -} - -void LLXmlTreeNode::dump( const std::string& prefix ) -{ - LL_INFOS() << prefix << mName ; - if( !mContents.empty() ) - { - LL_CONT << " contents = \"" << mContents << "\""; - } - attribute_map_t::iterator iter; - for (iter=mAttributes.begin(); iter != mAttributes.end(); iter++) - { - LLStdStringHandle key = iter->first; - const std::string* value = iter->second; - LL_CONT << prefix << " " << key << "=" << (value->empty() ? "NULL" : *value); - } - LL_CONT << LL_ENDL; -} - -bool LLXmlTreeNode::hasAttribute(const std::string& name) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString(name); - attribute_map_t::iterator iter = mAttributes.find(canonical_name); - return iter != mAttributes.end(); -} - -void LLXmlTreeNode::addAttribute(const std::string& name, const std::string& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString(name); - const std::string *newstr = new std::string(value); - mAttributes[canonical_name] = newstr; // insert + copy -} - -LLXmlTreeNode* LLXmlTreeNode::getFirstChild() -{ - mChildrenIter = mChildren.begin(); - return getNextChild(); -} -LLXmlTreeNode* LLXmlTreeNode::getNextChild() -{ - if (mChildrenIter == mChildren.end()) - return 0; - else - return *mChildrenIter++; -} - -LLXmlTreeNode* LLXmlTreeNode::getChildByName(const std::string& name) -{ - LLStdStringHandle tableptr = mTree->mNodeNames.checkString(name); - mChildMapIter = mChildMap.lower_bound(tableptr); - mChildMapEndIter = mChildMap.upper_bound(tableptr); - return getNextNamedChild(); -} - -LLXmlTreeNode* LLXmlTreeNode::getNextNamedChild() -{ - if (mChildMapIter == mChildMapEndIter) - return NULL; - else - return (mChildMapIter++)->second; -} - -void LLXmlTreeNode::appendContents(const std::string& str) -{ - mContents.append( str ); -} - -void LLXmlTreeNode::addChild(LLXmlTreeNode* child) -{ - llassert( child ); - mChildren.push_back( child ); - - // Add a name mapping to this node - LLStdStringHandle tableptr = mTree->mNodeNames.insert(child->mName); - mChildMap.insert( child_map_t::value_type(tableptr, child)); - - child->mParent = this; -} - -////////////////////////////////////////////////////////////// - -// These functions assume that name is already in mAttritrubteKeys - -bool LLXmlTreeNode::getFastAttributeBOOL(LLStdStringHandle canonical_name, bool& value) -{ - const std::string *s = getAttribute( canonical_name ); - return s && LLStringUtil::convertToBOOL( *s, value ); -} - -bool LLXmlTreeNode::getFastAttributeU8(LLStdStringHandle canonical_name, U8& value) -{ - const std::string *s = getAttribute( canonical_name ); - return s && LLStringUtil::convertToU8( *s, value ); -} - -bool LLXmlTreeNode::getFastAttributeS8(LLStdStringHandle canonical_name, S8& value) -{ - const std::string *s = getAttribute( canonical_name ); - return s && LLStringUtil::convertToS8( *s, value ); -} - -bool LLXmlTreeNode::getFastAttributeS16(LLStdStringHandle canonical_name, S16& value) -{ - const std::string *s = getAttribute( canonical_name ); - return s && LLStringUtil::convertToS16( *s, value ); -} - -bool LLXmlTreeNode::getFastAttributeU16(LLStdStringHandle canonical_name, U16& value) -{ - const std::string *s = getAttribute( canonical_name ); - return s && LLStringUtil::convertToU16( *s, value ); -} - -bool LLXmlTreeNode::getFastAttributeU32(LLStdStringHandle canonical_name, U32& value) -{ - const std::string *s = getAttribute( canonical_name ); - return s && LLStringUtil::convertToU32( *s, value ); -} - -bool LLXmlTreeNode::getFastAttributeS32(LLStdStringHandle canonical_name, S32& value) -{ - const std::string *s = getAttribute( canonical_name ); - return s && LLStringUtil::convertToS32( *s, value ); -} - -bool LLXmlTreeNode::getFastAttributeF32(LLStdStringHandle canonical_name, F32& value) -{ - const std::string *s = getAttribute( canonical_name ); - return s && LLStringUtil::convertToF32( *s, value ); -} - -bool LLXmlTreeNode::getFastAttributeF64(LLStdStringHandle canonical_name, F64& value) -{ - const std::string *s = getAttribute( canonical_name ); - return s && LLStringUtil::convertToF64( *s, value ); -} - -bool LLXmlTreeNode::getFastAttributeColor(LLStdStringHandle canonical_name, LLColor4& value) -{ - const std::string *s = getAttribute( canonical_name ); - return s ? LLColor4::parseColor(*s, &value) : false; -} - -bool LLXmlTreeNode::getFastAttributeColor4(LLStdStringHandle canonical_name, LLColor4& value) -{ - const std::string *s = getAttribute( canonical_name ); - return s ? LLColor4::parseColor4(*s, &value) : false; -} - -bool LLXmlTreeNode::getFastAttributeColor4U(LLStdStringHandle canonical_name, LLColor4U& value) -{ - const std::string *s = getAttribute( canonical_name ); - return s ? LLColor4U::parseColor4U(*s, &value ) : false; -} - -bool LLXmlTreeNode::getFastAttributeVector3(LLStdStringHandle canonical_name, LLVector3& value) -{ - const std::string *s = getAttribute( canonical_name ); - return s ? LLVector3::parseVector3(*s, &value ) : false; -} - -bool LLXmlTreeNode::getFastAttributeVector3d(LLStdStringHandle canonical_name, LLVector3d& value) -{ - const std::string *s = getAttribute( canonical_name ); - return s ? LLVector3d::parseVector3d(*s, &value ) : false; -} - -bool LLXmlTreeNode::getFastAttributeQuat(LLStdStringHandle canonical_name, LLQuaternion& value) -{ - const std::string *s = getAttribute( canonical_name ); - return s ? LLQuaternion::parseQuat(*s, &value ) : false; -} - -bool LLXmlTreeNode::getFastAttributeUUID(LLStdStringHandle canonical_name, LLUUID& value) -{ - const std::string *s = getAttribute( canonical_name ); - return s ? LLUUID::parseUUID(*s, &value ) : false; -} - -bool LLXmlTreeNode::getFastAttributeString(LLStdStringHandle canonical_name, std::string& value) -{ - const std::string *s = getAttribute( canonical_name ); - if( !s ) - { - return false; - } - - value = *s; - return true; -} - - -////////////////////////////////////////////////////////////// - -bool LLXmlTreeNode::getAttributeBOOL(const std::string& name, bool& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeBOOL(canonical_name, value); -} - -bool LLXmlTreeNode::getAttributeU8(const std::string& name, U8& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeU8(canonical_name, value); -} - -bool LLXmlTreeNode::getAttributeS8(const std::string& name, S8& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeS8(canonical_name, value); -} - -bool LLXmlTreeNode::getAttributeS16(const std::string& name, S16& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeS16(canonical_name, value); -} - -bool LLXmlTreeNode::getAttributeU16(const std::string& name, U16& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeU16(canonical_name, value); -} - -bool LLXmlTreeNode::getAttributeU32(const std::string& name, U32& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeU32(canonical_name, value); -} - -bool LLXmlTreeNode::getAttributeS32(const std::string& name, S32& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeS32(canonical_name, value); -} - -bool LLXmlTreeNode::getAttributeF32(const std::string& name, F32& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeF32(canonical_name, value); -} - -bool LLXmlTreeNode::getAttributeF64(const std::string& name, F64& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeF64(canonical_name, value); -} - -bool LLXmlTreeNode::getAttributeColor(const std::string& name, LLColor4& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeColor(canonical_name, value); -} - -bool LLXmlTreeNode::getAttributeColor4(const std::string& name, LLColor4& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeColor4(canonical_name, value); -} - -bool LLXmlTreeNode::getAttributeColor4U(const std::string& name, LLColor4U& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeColor4U(canonical_name, value); -} - -bool LLXmlTreeNode::getAttributeVector3(const std::string& name, LLVector3& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeVector3(canonical_name, value); -} - -bool LLXmlTreeNode::getAttributeVector3d(const std::string& name, LLVector3d& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeVector3d(canonical_name, value); -} - -bool LLXmlTreeNode::getAttributeQuat(const std::string& name, LLQuaternion& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeQuat(canonical_name, value); -} - -bool LLXmlTreeNode::getAttributeUUID(const std::string& name, LLUUID& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeUUID(canonical_name, value); -} - -bool LLXmlTreeNode::getAttributeString(const std::string& name, std::string& value) -{ - LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); - return getFastAttributeString(canonical_name, value); -} - -/* - The following xml nodes will all return the string from getTextContents(): - "The quick brown fox\n Jumps over the lazy dog" - - 1. HTML paragraph format: - -

The quick brown fox

-

Jumps over the lazy dog

-
- 2. Each quoted section -> paragraph: - - "The quick brown fox" - " Jumps over the lazy dog" - - 3. Literal text with beginning and trailing whitespace removed: - -The quick brown fox - Jumps over the lazy dog - - -*/ - -std::string LLXmlTreeNode::getTextContents() -{ - std::string msg; - LLXmlTreeNode* p = getChildByName("p"); - if (p) - { - // Case 1: node has

text

tags - while (p) - { - msg += p->getContents() + "\n"; - p = getNextNamedChild(); - } - } - else - { - std::string::size_type n = mContents.find_first_not_of(" \t\n"); - if (n != std::string::npos && mContents[n] == '\"') - { - // Case 2: node has quoted text - S32 num_lines = 0; - while(1) - { - // mContents[n] == '"' - ++n; - std::string::size_type t = n; - std::string::size_type m = 0; - // fix-up escaped characters - while(1) - { - m = mContents.find_first_of("\\\"", t); // find first \ or " - if ((m == std::string::npos) || (mContents[m] == '\"')) - { - break; - } - mContents.erase(m,1); - t = m+1; - } - if (m == std::string::npos) - { - break; - } - // mContents[m] == '"' - num_lines++; - msg += mContents.substr(n,m-n) + "\n"; - n = mContents.find_first_of("\"", m+1); - if (n == std::string::npos) - { - if (num_lines == 1) - { - msg.erase(msg.size()-1); // remove "\n" if only one line - } - break; - } - } - } - else - { - // Case 3: node has embedded text (beginning and trailing whitespace trimmed) - msg = mContents; - } - } - return msg; -} - - -////////////////////////////////////////////////////////////// -// LLXmlTreeParser - -LLXmlTreeParser::LLXmlTreeParser(LLXmlTree* tree) - : mTree(tree), - mRoot( NULL ), - mCurrent( NULL ), - mDump( false ), - mKeepContents(false) -{ -} - -LLXmlTreeParser::~LLXmlTreeParser() -{ -} - -bool LLXmlTreeParser::parseFile(const std::string &path, LLXmlTreeNode** root, bool keep_contents) -{ - llassert( !mRoot ); - llassert( !mCurrent ); - - mKeepContents = keep_contents; - - bool success = LLXmlParser::parseFile(path); - - *root = mRoot; - mRoot = NULL; - - if( success ) - { - llassert( !mCurrent ); - } - mCurrent = NULL; - - return success; -} - - -const std::string& LLXmlTreeParser::tabs() -{ - static std::string s; - s = ""; - S32 num_tabs = getDepth() - 1; - for( S32 i = 0; i < num_tabs; i++) - { - s += " "; - } - return s; -} - -void LLXmlTreeParser::startElement(const char* name, const char **atts) -{ - if( mDump ) - { - LL_INFOS() << tabs() << "startElement " << name << LL_ENDL; - - S32 i = 0; - while( atts[i] && atts[i+1] ) - { - LL_INFOS() << tabs() << "attribute: " << atts[i] << "=" << atts[i+1] << LL_ENDL; - i += 2; - } - } - - LLXmlTreeNode* child = CreateXmlTreeNode( std::string(name), mCurrent ); - - S32 i = 0; - while( atts[i] && atts[i+1] ) - { - child->addAttribute( atts[i], atts[i+1] ); - i += 2; - } - - if( mCurrent ) - { - mCurrent->addChild( child ); - - } - else - { - llassert( !mRoot ); - mRoot = child; - } - mCurrent = child; -} - -LLXmlTreeNode* LLXmlTreeParser::CreateXmlTreeNode(const std::string& name, LLXmlTreeNode* parent) -{ - return new LLXmlTreeNode(name, parent, mTree); -} - - -void LLXmlTreeParser::endElement(const char* name) -{ - if( mDump ) - { - LL_INFOS() << tabs() << "endElement " << name << LL_ENDL; - } - - if( !mCurrent->mContents.empty() ) - { - LLStringUtil::trim(mCurrent->mContents); - LLStringUtil::removeCRLF(mCurrent->mContents); - } - - mCurrent = mCurrent->getParent(); -} - -void LLXmlTreeParser::characterData(const char *s, int len) -{ - std::string str; - if (s) str = std::string(s, len); - if( mDump ) - { - LL_INFOS() << tabs() << "CharacterData " << str << LL_ENDL; - } - - if (mKeepContents) - { - mCurrent->appendContents( str ); - } -} - -void LLXmlTreeParser::processingInstruction(const char *target, const char *data) -{ - if( mDump ) - { - LL_INFOS() << tabs() << "processingInstruction " << data << LL_ENDL; - } -} - -void LLXmlTreeParser::comment(const char *data) -{ - if( mDump ) - { - LL_INFOS() << tabs() << "comment " << data << LL_ENDL; - } -} - -void LLXmlTreeParser::startCdataSection() -{ - if( mDump ) - { - LL_INFOS() << tabs() << "startCdataSection" << LL_ENDL; - } -} - -void LLXmlTreeParser::endCdataSection() -{ - if( mDump ) - { - LL_INFOS() << tabs() << "endCdataSection" << LL_ENDL; - } -} - -void LLXmlTreeParser::defaultData(const char *s, int len) -{ - if( mDump ) - { - std::string str; - if (s) str = std::string(s, len); - LL_INFOS() << tabs() << "defaultData " << str << LL_ENDL; - } -} - -void LLXmlTreeParser::unparsedEntityDecl( - const char* entity_name, - const char* base, - const char* system_id, - const char* public_id, - const char* notation_name) -{ - if( mDump ) - { - LL_INFOS() << tabs() << "unparsed entity:" << LL_ENDL; - LL_INFOS() << tabs() << " entityName " << entity_name << LL_ENDL; - LL_INFOS() << tabs() << " base " << base << LL_ENDL; - LL_INFOS() << tabs() << " systemId " << system_id << LL_ENDL; - LL_INFOS() << tabs() << " publicId " << public_id << LL_ENDL; - LL_INFOS() << tabs() << " notationName " << notation_name<< LL_ENDL; - } -} - -void test_llxmltree() -{ - LLXmlTree tree; - bool success = tree.parseFile( "test.xml" ); - if( success ) - { - tree.dump(); - } -} - +/** + * @file llxmltree.cpp + * @brief LLXmlTree implementation + * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llxmltree.h" +#include "v3color.h" +#include "v4color.h" +#include "v4coloru.h" +#include "v3math.h" +#include "v3dmath.h" +#include "v4math.h" +#include "llquaternion.h" +#include "lluuid.h" + +////////////////////////////////////////////////////////////// +// LLXmlTree + +// static +LLStdStringTable LLXmlTree::sAttributeKeys(1024); + +LLXmlTree::LLXmlTree() + : mRoot( NULL ), + mNodeNames(512) +{ +} + +LLXmlTree::~LLXmlTree() +{ + cleanup(); +} + +void LLXmlTree::cleanup() +{ + delete mRoot; + mRoot = NULL; + mNodeNames.cleanup(); +} + + +bool LLXmlTree::parseFile(const std::string &path, bool keep_contents) +{ + delete mRoot; + mRoot = NULL; + + LLXmlTreeParser parser(this); + 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; +} + +void LLXmlTree::dump() +{ + if( mRoot ) + { + dumpNode( mRoot, " " ); + } +} + +void LLXmlTree::dumpNode( LLXmlTreeNode* node, const std::string& prefix ) +{ + node->dump( prefix ); + + std::string new_prefix = prefix + " "; + for( LLXmlTreeNode* child = node->getFirstChild(); child; child = node->getNextChild() ) + { + dumpNode( child, new_prefix ); + } +} + +////////////////////////////////////////////////////////////// +// LLXmlTreeNode + +LLXmlTreeNode::LLXmlTreeNode( const std::string& name, LLXmlTreeNode* parent, LLXmlTree* tree ) + : mName(name), + mParent(parent), + mTree(tree) +{ +} + +LLXmlTreeNode::~LLXmlTreeNode() +{ + attribute_map_t::iterator iter; + for (iter=mAttributes.begin(); iter != mAttributes.end(); iter++) + delete iter->second; + for(LLXmlTreeNode* node : mChildren) + { + delete node; + } + mChildren.clear(); +} + +void LLXmlTreeNode::dump( const std::string& prefix ) +{ + LL_INFOS() << prefix << mName ; + if( !mContents.empty() ) + { + LL_CONT << " contents = \"" << mContents << "\""; + } + attribute_map_t::iterator iter; + for (iter=mAttributes.begin(); iter != mAttributes.end(); iter++) + { + LLStdStringHandle key = iter->first; + const std::string* value = iter->second; + LL_CONT << prefix << " " << key << "=" << (value->empty() ? "NULL" : *value); + } + LL_CONT << LL_ENDL; +} + +bool LLXmlTreeNode::hasAttribute(const std::string& name) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString(name); + attribute_map_t::iterator iter = mAttributes.find(canonical_name); + return iter != mAttributes.end(); +} + +void LLXmlTreeNode::addAttribute(const std::string& name, const std::string& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString(name); + const std::string *newstr = new std::string(value); + mAttributes[canonical_name] = newstr; // insert + copy +} + +LLXmlTreeNode* LLXmlTreeNode::getFirstChild() +{ + mChildrenIter = mChildren.begin(); + return getNextChild(); +} +LLXmlTreeNode* LLXmlTreeNode::getNextChild() +{ + if (mChildrenIter == mChildren.end()) + return 0; + else + return *mChildrenIter++; +} + +LLXmlTreeNode* LLXmlTreeNode::getChildByName(const std::string& name) +{ + LLStdStringHandle tableptr = mTree->mNodeNames.checkString(name); + mChildMapIter = mChildMap.lower_bound(tableptr); + mChildMapEndIter = mChildMap.upper_bound(tableptr); + return getNextNamedChild(); +} + +LLXmlTreeNode* LLXmlTreeNode::getNextNamedChild() +{ + if (mChildMapIter == mChildMapEndIter) + return NULL; + else + return (mChildMapIter++)->second; +} + +void LLXmlTreeNode::appendContents(const std::string& str) +{ + mContents.append( str ); +} + +void LLXmlTreeNode::addChild(LLXmlTreeNode* child) +{ + llassert( child ); + mChildren.push_back( child ); + + // Add a name mapping to this node + LLStdStringHandle tableptr = mTree->mNodeNames.insert(child->mName); + mChildMap.insert( child_map_t::value_type(tableptr, child)); + + child->mParent = this; +} + +////////////////////////////////////////////////////////////// + +// These functions assume that name is already in mAttritrubteKeys + +bool LLXmlTreeNode::getFastAttributeBOOL(LLStdStringHandle canonical_name, bool& value) +{ + const std::string *s = getAttribute( canonical_name ); + return s && LLStringUtil::convertToBOOL( *s, value ); +} + +bool LLXmlTreeNode::getFastAttributeU8(LLStdStringHandle canonical_name, U8& value) +{ + const std::string *s = getAttribute( canonical_name ); + return s && LLStringUtil::convertToU8( *s, value ); +} + +bool LLXmlTreeNode::getFastAttributeS8(LLStdStringHandle canonical_name, S8& value) +{ + const std::string *s = getAttribute( canonical_name ); + return s && LLStringUtil::convertToS8( *s, value ); +} + +bool LLXmlTreeNode::getFastAttributeS16(LLStdStringHandle canonical_name, S16& value) +{ + const std::string *s = getAttribute( canonical_name ); + return s && LLStringUtil::convertToS16( *s, value ); +} + +bool LLXmlTreeNode::getFastAttributeU16(LLStdStringHandle canonical_name, U16& value) +{ + const std::string *s = getAttribute( canonical_name ); + return s && LLStringUtil::convertToU16( *s, value ); +} + +bool LLXmlTreeNode::getFastAttributeU32(LLStdStringHandle canonical_name, U32& value) +{ + const std::string *s = getAttribute( canonical_name ); + return s && LLStringUtil::convertToU32( *s, value ); +} + +bool LLXmlTreeNode::getFastAttributeS32(LLStdStringHandle canonical_name, S32& value) +{ + const std::string *s = getAttribute( canonical_name ); + return s && LLStringUtil::convertToS32( *s, value ); +} + +bool LLXmlTreeNode::getFastAttributeF32(LLStdStringHandle canonical_name, F32& value) +{ + const std::string *s = getAttribute( canonical_name ); + return s && LLStringUtil::convertToF32( *s, value ); +} + +bool LLXmlTreeNode::getFastAttributeF64(LLStdStringHandle canonical_name, F64& value) +{ + const std::string *s = getAttribute( canonical_name ); + return s && LLStringUtil::convertToF64( *s, value ); +} + +bool LLXmlTreeNode::getFastAttributeColor(LLStdStringHandle canonical_name, LLColor4& value) +{ + const std::string *s = getAttribute( canonical_name ); + return s ? LLColor4::parseColor(*s, &value) : false; +} + +bool LLXmlTreeNode::getFastAttributeColor4(LLStdStringHandle canonical_name, LLColor4& value) +{ + const std::string *s = getAttribute( canonical_name ); + return s ? LLColor4::parseColor4(*s, &value) : false; +} + +bool LLXmlTreeNode::getFastAttributeColor4U(LLStdStringHandle canonical_name, LLColor4U& value) +{ + const std::string *s = getAttribute( canonical_name ); + return s ? LLColor4U::parseColor4U(*s, &value ) : false; +} + +bool LLXmlTreeNode::getFastAttributeVector3(LLStdStringHandle canonical_name, LLVector3& value) +{ + const std::string *s = getAttribute( canonical_name ); + return s ? LLVector3::parseVector3(*s, &value ) : false; +} + +bool LLXmlTreeNode::getFastAttributeVector3d(LLStdStringHandle canonical_name, LLVector3d& value) +{ + const std::string *s = getAttribute( canonical_name ); + return s ? LLVector3d::parseVector3d(*s, &value ) : false; +} + +bool LLXmlTreeNode::getFastAttributeQuat(LLStdStringHandle canonical_name, LLQuaternion& value) +{ + const std::string *s = getAttribute( canonical_name ); + return s ? LLQuaternion::parseQuat(*s, &value ) : false; +} + +bool LLXmlTreeNode::getFastAttributeUUID(LLStdStringHandle canonical_name, LLUUID& value) +{ + const std::string *s = getAttribute( canonical_name ); + return s ? LLUUID::parseUUID(*s, &value ) : false; +} + +bool LLXmlTreeNode::getFastAttributeString(LLStdStringHandle canonical_name, std::string& value) +{ + const std::string *s = getAttribute( canonical_name ); + if( !s ) + { + return false; + } + + value = *s; + return true; +} + + +////////////////////////////////////////////////////////////// + +bool LLXmlTreeNode::getAttributeBOOL(const std::string& name, bool& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeBOOL(canonical_name, value); +} + +bool LLXmlTreeNode::getAttributeU8(const std::string& name, U8& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeU8(canonical_name, value); +} + +bool LLXmlTreeNode::getAttributeS8(const std::string& name, S8& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeS8(canonical_name, value); +} + +bool LLXmlTreeNode::getAttributeS16(const std::string& name, S16& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeS16(canonical_name, value); +} + +bool LLXmlTreeNode::getAttributeU16(const std::string& name, U16& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeU16(canonical_name, value); +} + +bool LLXmlTreeNode::getAttributeU32(const std::string& name, U32& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeU32(canonical_name, value); +} + +bool LLXmlTreeNode::getAttributeS32(const std::string& name, S32& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeS32(canonical_name, value); +} + +bool LLXmlTreeNode::getAttributeF32(const std::string& name, F32& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeF32(canonical_name, value); +} + +bool LLXmlTreeNode::getAttributeF64(const std::string& name, F64& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeF64(canonical_name, value); +} + +bool LLXmlTreeNode::getAttributeColor(const std::string& name, LLColor4& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeColor(canonical_name, value); +} + +bool LLXmlTreeNode::getAttributeColor4(const std::string& name, LLColor4& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeColor4(canonical_name, value); +} + +bool LLXmlTreeNode::getAttributeColor4U(const std::string& name, LLColor4U& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeColor4U(canonical_name, value); +} + +bool LLXmlTreeNode::getAttributeVector3(const std::string& name, LLVector3& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeVector3(canonical_name, value); +} + +bool LLXmlTreeNode::getAttributeVector3d(const std::string& name, LLVector3d& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeVector3d(canonical_name, value); +} + +bool LLXmlTreeNode::getAttributeQuat(const std::string& name, LLQuaternion& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeQuat(canonical_name, value); +} + +bool LLXmlTreeNode::getAttributeUUID(const std::string& name, LLUUID& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeUUID(canonical_name, value); +} + +bool LLXmlTreeNode::getAttributeString(const std::string& name, std::string& value) +{ + LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name ); + return getFastAttributeString(canonical_name, value); +} + +/* + The following xml nodes will all return the string from getTextContents(): + "The quick brown fox\n Jumps over the lazy dog" + + 1. HTML paragraph format: + +

The quick brown fox

+

Jumps over the lazy dog

+
+ 2. Each quoted section -> paragraph: + + "The quick brown fox" + " Jumps over the lazy dog" + + 3. Literal text with beginning and trailing whitespace removed: + +The quick brown fox + Jumps over the lazy dog + + +*/ + +std::string LLXmlTreeNode::getTextContents() +{ + std::string msg; + LLXmlTreeNode* p = getChildByName("p"); + if (p) + { + // Case 1: node has

text

tags + while (p) + { + msg += p->getContents() + "\n"; + p = getNextNamedChild(); + } + } + else + { + std::string::size_type n = mContents.find_first_not_of(" \t\n"); + if (n != std::string::npos && mContents[n] == '\"') + { + // Case 2: node has quoted text + S32 num_lines = 0; + while(1) + { + // mContents[n] == '"' + ++n; + std::string::size_type t = n; + std::string::size_type m = 0; + // fix-up escaped characters + while(1) + { + m = mContents.find_first_of("\\\"", t); // find first \ or " + if ((m == std::string::npos) || (mContents[m] == '\"')) + { + break; + } + mContents.erase(m,1); + t = m+1; + } + if (m == std::string::npos) + { + break; + } + // mContents[m] == '"' + num_lines++; + msg += mContents.substr(n,m-n) + "\n"; + n = mContents.find_first_of("\"", m+1); + if (n == std::string::npos) + { + if (num_lines == 1) + { + msg.erase(msg.size()-1); // remove "\n" if only one line + } + break; + } + } + } + else + { + // Case 3: node has embedded text (beginning and trailing whitespace trimmed) + msg = mContents; + } + } + return msg; +} + + +////////////////////////////////////////////////////////////// +// LLXmlTreeParser + +LLXmlTreeParser::LLXmlTreeParser(LLXmlTree* tree) + : mTree(tree), + mRoot( NULL ), + mCurrent( NULL ), + mDump( false ), + mKeepContents(false) +{ +} + +LLXmlTreeParser::~LLXmlTreeParser() +{ +} + +bool LLXmlTreeParser::parseFile(const std::string &path, LLXmlTreeNode** root, bool keep_contents) +{ + llassert( !mRoot ); + llassert( !mCurrent ); + + mKeepContents = keep_contents; + + bool success = LLXmlParser::parseFile(path); + + *root = mRoot; + mRoot = NULL; + + if( success ) + { + llassert( !mCurrent ); + } + mCurrent = NULL; + + return success; +} + + +const std::string& LLXmlTreeParser::tabs() +{ + static std::string s; + s = ""; + S32 num_tabs = getDepth() - 1; + for( S32 i = 0; i < num_tabs; i++) + { + s += " "; + } + return s; +} + +void LLXmlTreeParser::startElement(const char* name, const char **atts) +{ + if( mDump ) + { + LL_INFOS() << tabs() << "startElement " << name << LL_ENDL; + + S32 i = 0; + while( atts[i] && atts[i+1] ) + { + LL_INFOS() << tabs() << "attribute: " << atts[i] << "=" << atts[i+1] << LL_ENDL; + i += 2; + } + } + + LLXmlTreeNode* child = CreateXmlTreeNode( std::string(name), mCurrent ); + + S32 i = 0; + while( atts[i] && atts[i+1] ) + { + child->addAttribute( atts[i], atts[i+1] ); + i += 2; + } + + if( mCurrent ) + { + mCurrent->addChild( child ); + + } + else + { + llassert( !mRoot ); + mRoot = child; + } + mCurrent = child; +} + +LLXmlTreeNode* LLXmlTreeParser::CreateXmlTreeNode(const std::string& name, LLXmlTreeNode* parent) +{ + return new LLXmlTreeNode(name, parent, mTree); +} + + +void LLXmlTreeParser::endElement(const char* name) +{ + if( mDump ) + { + LL_INFOS() << tabs() << "endElement " << name << LL_ENDL; + } + + if( !mCurrent->mContents.empty() ) + { + LLStringUtil::trim(mCurrent->mContents); + LLStringUtil::removeCRLF(mCurrent->mContents); + } + + mCurrent = mCurrent->getParent(); +} + +void LLXmlTreeParser::characterData(const char *s, int len) +{ + std::string str; + if (s) str = std::string(s, len); + if( mDump ) + { + LL_INFOS() << tabs() << "CharacterData " << str << LL_ENDL; + } + + if (mKeepContents) + { + mCurrent->appendContents( str ); + } +} + +void LLXmlTreeParser::processingInstruction(const char *target, const char *data) +{ + if( mDump ) + { + LL_INFOS() << tabs() << "processingInstruction " << data << LL_ENDL; + } +} + +void LLXmlTreeParser::comment(const char *data) +{ + if( mDump ) + { + LL_INFOS() << tabs() << "comment " << data << LL_ENDL; + } +} + +void LLXmlTreeParser::startCdataSection() +{ + if( mDump ) + { + LL_INFOS() << tabs() << "startCdataSection" << LL_ENDL; + } +} + +void LLXmlTreeParser::endCdataSection() +{ + if( mDump ) + { + LL_INFOS() << tabs() << "endCdataSection" << LL_ENDL; + } +} + +void LLXmlTreeParser::defaultData(const char *s, int len) +{ + if( mDump ) + { + std::string str; + if (s) str = std::string(s, len); + LL_INFOS() << tabs() << "defaultData " << str << LL_ENDL; + } +} + +void LLXmlTreeParser::unparsedEntityDecl( + const char* entity_name, + const char* base, + const char* system_id, + const char* public_id, + const char* notation_name) +{ + if( mDump ) + { + LL_INFOS() << tabs() << "unparsed entity:" << LL_ENDL; + LL_INFOS() << tabs() << " entityName " << entity_name << LL_ENDL; + LL_INFOS() << tabs() << " base " << base << LL_ENDL; + LL_INFOS() << tabs() << " systemId " << system_id << LL_ENDL; + LL_INFOS() << tabs() << " publicId " << public_id << LL_ENDL; + LL_INFOS() << tabs() << " notationName " << notation_name<< LL_ENDL; + } +} + +void test_llxmltree() +{ + LLXmlTree tree; + bool success = tree.parseFile( "test.xml" ); + if( success ) + { + tree.dump(); + } +} + diff --git a/indra/llxml/llxmltree.h b/indra/llxml/llxmltree.h index 570edee5ad..120d7d3e56 100644 --- a/indra/llxml/llxmltree.h +++ b/indra/llxml/llxmltree.h @@ -1,234 +1,234 @@ -/** - * @file llxmltree.h - * @author Aaron Yonas, Richard Nelson - * @brief LLXmlTree class definition - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLXMLTREE_H -#define LL_LLXMLTREE_H - -#include -#include -#include "llstring.h" -#include "llxmlparser.h" -#include "llstringtable.h" - -class LLColor4; -class LLColor4U; -class LLQuaternion; -class LLUUID; -class LLVector3; -class LLVector3d; -class LLXmlTreeNode; -class LLXmlTreeParser; - -////////////////////////////////////////////////////////////// -// LLXmlTree - -class LLXmlTree -{ - friend class LLXmlTreeNode; - -public: - LLXmlTree(); - virtual ~LLXmlTree(); - void cleanup(); - - virtual bool parseFile(const std::string &path, bool keep_contents = true); - - LLXmlTreeNode* getRoot() { return mRoot; } - - void dump(); - void dumpNode( LLXmlTreeNode* node, const std::string& prefix ); - - static LLStdStringHandle addAttributeString( const std::string& name) - { - return sAttributeKeys.addString( name ); - } - -public: - // global - static LLStdStringTable sAttributeKeys; - -protected: - LLXmlTreeNode* mRoot; - - // local - LLStdStringTable mNodeNames; -}; - -////////////////////////////////////////////////////////////// -// LLXmlTreeNode - -class LLXmlTreeNode -{ - friend class LLXmlTree; - friend class LLXmlTreeParser; - -protected: - // Protected since nodes are only created and destroyed by friend classes and other LLXmlTreeNodes - LLXmlTreeNode( const std::string& name, LLXmlTreeNode* parent, LLXmlTree* tree ); - -public: - virtual ~LLXmlTreeNode(); - - const std::string& getName() - { - return mName; - } - bool hasName( const std::string& name ) - { - return mName == name; - } - - bool hasAttribute( const std::string& name ); - - // Fast versions use cannonical_name handlee to entru in LLXmlTree::sAttributeKeys string table - bool getFastAttributeBOOL( LLStdStringHandle cannonical_name, bool& value ); - bool getFastAttributeU8( LLStdStringHandle cannonical_name, U8& value ); - bool getFastAttributeS8( LLStdStringHandle cannonical_name, S8& value ); - bool getFastAttributeU16( LLStdStringHandle cannonical_name, U16& value ); - bool getFastAttributeS16( LLStdStringHandle cannonical_name, S16& value ); - bool getFastAttributeU32( LLStdStringHandle cannonical_name, U32& value ); - bool getFastAttributeS32( LLStdStringHandle cannonical_name, S32& value ); - bool getFastAttributeF32( LLStdStringHandle cannonical_name, F32& value ); - bool getFastAttributeF64( LLStdStringHandle cannonical_name, F64& value ); - bool getFastAttributeColor( LLStdStringHandle cannonical_name, LLColor4& value ); - bool getFastAttributeColor4( LLStdStringHandle cannonical_name, LLColor4& value ); - bool getFastAttributeColor4U( LLStdStringHandle cannonical_name, LLColor4U& value ); - bool getFastAttributeVector3( LLStdStringHandle cannonical_name, LLVector3& value ); - bool getFastAttributeVector3d( LLStdStringHandle cannonical_name, LLVector3d& value ); - bool getFastAttributeQuat( LLStdStringHandle cannonical_name, LLQuaternion& value ); - bool getFastAttributeUUID( LLStdStringHandle cannonical_name, LLUUID& value ); - bool getFastAttributeString( LLStdStringHandle cannonical_name, std::string& value ); - - // Normal versions find 'name' in LLXmlTree::sAttributeKeys then call fast versions - virtual bool getAttributeBOOL( const std::string& name, bool& value ); - virtual bool getAttributeU8( const std::string& name, U8& value ); - virtual bool getAttributeS8( const std::string& name, S8& value ); - virtual bool getAttributeU16( const std::string& name, U16& value ); - virtual bool getAttributeS16( const std::string& name, S16& value ); - virtual bool getAttributeU32( const std::string& name, U32& value ); - virtual bool getAttributeS32( const std::string& name, S32& value ); - virtual bool getAttributeF32( const std::string& name, F32& value ); - virtual bool getAttributeF64( const std::string& name, F64& value ); - virtual bool getAttributeColor( const std::string& name, LLColor4& value ); - virtual bool getAttributeColor4( const std::string& name, LLColor4& value ); - virtual bool getAttributeColor4U( const std::string& name, LLColor4U& value ); - virtual bool getAttributeVector3( const std::string& name, LLVector3& value ); - virtual bool getAttributeVector3d( const std::string& name, LLVector3d& value ); - virtual bool getAttributeQuat( const std::string& name, LLQuaternion& value ); - virtual bool getAttributeUUID( const std::string& name, LLUUID& value ); - virtual bool getAttributeString( const std::string& name, std::string& value ); - - const std::string& getContents() - { - return mContents; - } - std::string getTextContents(); - - LLXmlTreeNode* getParent() { return mParent; } - LLXmlTreeNode* getFirstChild(); - LLXmlTreeNode* getNextChild(); - S32 getChildCount() { return (S32)mChildren.size(); } - LLXmlTreeNode* getChildByName( const std::string& name ); // returns first child with name, NULL if none - LLXmlTreeNode* getNextNamedChild(); // returns next child with name, NULL if none - -protected: - const std::string* getAttribute( LLStdStringHandle name) - { - attribute_map_t::iterator iter = mAttributes.find(name); - return (iter == mAttributes.end()) ? 0 : iter->second; - } - -private: - void addAttribute( const std::string& name, const std::string& value ); - void appendContents( const std::string& str ); - void addChild( LLXmlTreeNode* child ); - - void dump( const std::string& prefix ); - -protected: - typedef std::map attribute_map_t; - attribute_map_t mAttributes; - -private: - std::string mName; - std::string mContents; - - typedef std::vector children_t; - children_t mChildren; - children_t::iterator mChildrenIter; - - typedef std::multimap child_map_t; - child_map_t mChildMap; // for fast name lookups - child_map_t::iterator mChildMapIter; - child_map_t::iterator mChildMapEndIter; - - LLXmlTreeNode* mParent; - LLXmlTree* mTree; -}; - -////////////////////////////////////////////////////////////// -// LLXmlTreeParser - -class LLXmlTreeParser : public LLXmlParser -{ -public: - LLXmlTreeParser(LLXmlTree* tree); - virtual ~LLXmlTreeParser(); - - bool parseFile(const std::string &path, LLXmlTreeNode** root, bool keep_contents ); - -protected: - const std::string& tabs(); - - // Overrides from LLXmlParser - virtual void startElement(const char *name, const char **attributes); - virtual void endElement(const char *name); - virtual void characterData(const char *s, int len); - virtual void processingInstruction(const char *target, const char *data); - virtual void comment(const char *data); - virtual void startCdataSection(); - virtual void endCdataSection(); - virtual void defaultData(const char *s, int len); - virtual void unparsedEntityDecl( - const char* entity_name, - const char* base, - const char* system_id, - const char* public_id, - const char* notation_name); - - //template method pattern - virtual LLXmlTreeNode* CreateXmlTreeNode(const std::string& name, LLXmlTreeNode* parent); - -protected: - LLXmlTree* mTree; - LLXmlTreeNode* mRoot; - LLXmlTreeNode* mCurrent; - bool mDump; // Dump parse tree to LL_INFOS() as it is read. - bool mKeepContents; -}; - -#endif // LL_LLXMLTREE_H +/** + * @file llxmltree.h + * @author Aaron Yonas, Richard Nelson + * @brief LLXmlTree class definition + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLXMLTREE_H +#define LL_LLXMLTREE_H + +#include +#include +#include "llstring.h" +#include "llxmlparser.h" +#include "llstringtable.h" + +class LLColor4; +class LLColor4U; +class LLQuaternion; +class LLUUID; +class LLVector3; +class LLVector3d; +class LLXmlTreeNode; +class LLXmlTreeParser; + +////////////////////////////////////////////////////////////// +// LLXmlTree + +class LLXmlTree +{ + friend class LLXmlTreeNode; + +public: + LLXmlTree(); + virtual ~LLXmlTree(); + void cleanup(); + + virtual bool parseFile(const std::string &path, bool keep_contents = true); + + LLXmlTreeNode* getRoot() { return mRoot; } + + void dump(); + void dumpNode( LLXmlTreeNode* node, const std::string& prefix ); + + static LLStdStringHandle addAttributeString( const std::string& name) + { + return sAttributeKeys.addString( name ); + } + +public: + // global + static LLStdStringTable sAttributeKeys; + +protected: + LLXmlTreeNode* mRoot; + + // local + LLStdStringTable mNodeNames; +}; + +////////////////////////////////////////////////////////////// +// LLXmlTreeNode + +class LLXmlTreeNode +{ + friend class LLXmlTree; + friend class LLXmlTreeParser; + +protected: + // Protected since nodes are only created and destroyed by friend classes and other LLXmlTreeNodes + LLXmlTreeNode( const std::string& name, LLXmlTreeNode* parent, LLXmlTree* tree ); + +public: + virtual ~LLXmlTreeNode(); + + const std::string& getName() + { + return mName; + } + bool hasName( const std::string& name ) + { + return mName == name; + } + + bool hasAttribute( const std::string& name ); + + // Fast versions use cannonical_name handlee to entru in LLXmlTree::sAttributeKeys string table + bool getFastAttributeBOOL( LLStdStringHandle cannonical_name, bool& value ); + bool getFastAttributeU8( LLStdStringHandle cannonical_name, U8& value ); + bool getFastAttributeS8( LLStdStringHandle cannonical_name, S8& value ); + bool getFastAttributeU16( LLStdStringHandle cannonical_name, U16& value ); + bool getFastAttributeS16( LLStdStringHandle cannonical_name, S16& value ); + bool getFastAttributeU32( LLStdStringHandle cannonical_name, U32& value ); + bool getFastAttributeS32( LLStdStringHandle cannonical_name, S32& value ); + bool getFastAttributeF32( LLStdStringHandle cannonical_name, F32& value ); + bool getFastAttributeF64( LLStdStringHandle cannonical_name, F64& value ); + bool getFastAttributeColor( LLStdStringHandle cannonical_name, LLColor4& value ); + bool getFastAttributeColor4( LLStdStringHandle cannonical_name, LLColor4& value ); + bool getFastAttributeColor4U( LLStdStringHandle cannonical_name, LLColor4U& value ); + bool getFastAttributeVector3( LLStdStringHandle cannonical_name, LLVector3& value ); + bool getFastAttributeVector3d( LLStdStringHandle cannonical_name, LLVector3d& value ); + bool getFastAttributeQuat( LLStdStringHandle cannonical_name, LLQuaternion& value ); + bool getFastAttributeUUID( LLStdStringHandle cannonical_name, LLUUID& value ); + bool getFastAttributeString( LLStdStringHandle cannonical_name, std::string& value ); + + // Normal versions find 'name' in LLXmlTree::sAttributeKeys then call fast versions + virtual bool getAttributeBOOL( const std::string& name, bool& value ); + virtual bool getAttributeU8( const std::string& name, U8& value ); + virtual bool getAttributeS8( const std::string& name, S8& value ); + virtual bool getAttributeU16( const std::string& name, U16& value ); + virtual bool getAttributeS16( const std::string& name, S16& value ); + virtual bool getAttributeU32( const std::string& name, U32& value ); + virtual bool getAttributeS32( const std::string& name, S32& value ); + virtual bool getAttributeF32( const std::string& name, F32& value ); + virtual bool getAttributeF64( const std::string& name, F64& value ); + virtual bool getAttributeColor( const std::string& name, LLColor4& value ); + virtual bool getAttributeColor4( const std::string& name, LLColor4& value ); + virtual bool getAttributeColor4U( const std::string& name, LLColor4U& value ); + virtual bool getAttributeVector3( const std::string& name, LLVector3& value ); + virtual bool getAttributeVector3d( const std::string& name, LLVector3d& value ); + virtual bool getAttributeQuat( const std::string& name, LLQuaternion& value ); + virtual bool getAttributeUUID( const std::string& name, LLUUID& value ); + virtual bool getAttributeString( const std::string& name, std::string& value ); + + const std::string& getContents() + { + return mContents; + } + std::string getTextContents(); + + LLXmlTreeNode* getParent() { return mParent; } + LLXmlTreeNode* getFirstChild(); + LLXmlTreeNode* getNextChild(); + S32 getChildCount() { return (S32)mChildren.size(); } + LLXmlTreeNode* getChildByName( const std::string& name ); // returns first child with name, NULL if none + LLXmlTreeNode* getNextNamedChild(); // returns next child with name, NULL if none + +protected: + const std::string* getAttribute( LLStdStringHandle name) + { + attribute_map_t::iterator iter = mAttributes.find(name); + return (iter == mAttributes.end()) ? 0 : iter->second; + } + +private: + void addAttribute( const std::string& name, const std::string& value ); + void appendContents( const std::string& str ); + void addChild( LLXmlTreeNode* child ); + + void dump( const std::string& prefix ); + +protected: + typedef std::map attribute_map_t; + attribute_map_t mAttributes; + +private: + std::string mName; + std::string mContents; + + typedef std::vector children_t; + children_t mChildren; + children_t::iterator mChildrenIter; + + typedef std::multimap child_map_t; + child_map_t mChildMap; // for fast name lookups + child_map_t::iterator mChildMapIter; + child_map_t::iterator mChildMapEndIter; + + LLXmlTreeNode* mParent; + LLXmlTree* mTree; +}; + +////////////////////////////////////////////////////////////// +// LLXmlTreeParser + +class LLXmlTreeParser : public LLXmlParser +{ +public: + LLXmlTreeParser(LLXmlTree* tree); + virtual ~LLXmlTreeParser(); + + bool parseFile(const std::string &path, LLXmlTreeNode** root, bool keep_contents ); + +protected: + const std::string& tabs(); + + // Overrides from LLXmlParser + virtual void startElement(const char *name, const char **attributes); + virtual void endElement(const char *name); + virtual void characterData(const char *s, int len); + virtual void processingInstruction(const char *target, const char *data); + virtual void comment(const char *data); + virtual void startCdataSection(); + virtual void endCdataSection(); + virtual void defaultData(const char *s, int len); + virtual void unparsedEntityDecl( + const char* entity_name, + const char* base, + const char* system_id, + const char* public_id, + const char* notation_name); + + //template method pattern + virtual LLXmlTreeNode* CreateXmlTreeNode(const std::string& name, LLXmlTreeNode* parent); + +protected: + LLXmlTree* mTree; + LLXmlTreeNode* mRoot; + LLXmlTreeNode* mCurrent; + bool mDump; // Dump parse tree to LL_INFOS() as it is read. + bool mKeepContents; +}; + +#endif // LL_LLXMLTREE_H diff --git a/indra/llxml/tests/llcontrol_test.cpp b/indra/llxml/tests/llcontrol_test.cpp index 2025111363..4192e029c5 100644 --- a/indra/llxml/tests/llcontrol_test.cpp +++ b/indra/llxml/tests/llcontrol_test.cpp @@ -1,154 +1,154 @@ -/** - * @file llcontrol_tut.cpp - * @date February 2008 - * @brief control group unit tests - * - * $LicenseInfo:firstyear=2008&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" -#include "llsdserialize.h" -#include "llfile.h" -#include "stringize.h" - -#include "../llcontrol.h" - -#include "../test/lltut.h" -#include -#include - -namespace tut -{ - struct control_group - { - std::unique_ptr mCG; - std::string mTestConfigDir; - std::string mTestConfigFile; - std::vector mCleanups; - static bool mListenerFired; - control_group() - { - mCG.reset(new LLControlGroup("foo")); - LLUUID random; - random.generate(); - // generate temp dir - mTestConfigDir = STRINGIZE(LLFile::tmpdir() << "llcontrol-test-" << random << "/"); - mTestConfigFile = mTestConfigDir + "settings.xml"; - LLFile::mkdir(mTestConfigDir); - LLSD config; - config["TestSetting"]["Comment"] = "Dummy setting used for testing"; - config["TestSetting"]["Persist"] = 1; - config["TestSetting"]["Type"] = "U32"; - config["TestSetting"]["Value"] = 12; - writeSettingsFile(config); - } - ~control_group() - { - //Remove test files - for (auto filename : mCleanups) - { - LLFile::remove(filename); - } - LLFile::remove(mTestConfigFile); - LLFile::rmdir(mTestConfigDir); - } - void writeSettingsFile(const LLSD& config) - { - llofstream file(mTestConfigFile.c_str()); - if (file.is_open()) - { - LLSDSerialize::toPrettyXML(config, file); - } - file.close(); - } - static bool handleListenerTest() - { - control_group::mListenerFired = true; - return true; - } - }; - - bool control_group::mListenerFired = false; - - typedef test_group control_group_test; - typedef control_group_test::object control_group_t; - control_group_test tut_control_group("control_group"); - - //load settings from files - LLSD - template<> template<> - void control_group_t::test<1>() - { - int results = mCG->loadFromFile(mTestConfigFile.c_str()); - ensure("number of settings", (results == 1)); - ensure("value of setting", (mCG->getU32("TestSetting") == 12)); - } - - //save settings to files - template<> template<> - void control_group_t::test<2>() - { - int results = mCG->loadFromFile(mTestConfigFile.c_str()); - mCG->setU32("TestSetting", 13); - ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13); - LLControlGroup test_cg("foo2"); - std::string temp_test_file = (mTestConfigDir + "setting_llsd_temp.xml"); - mCleanups.push_back(temp_test_file); - mCG->saveToFile(temp_test_file.c_str(), true); - results = test_cg.loadFromFile(temp_test_file.c_str()); - ensure("number of changed settings loaded", (results == 1)); - ensure("value of changed settings loaded", (test_cg.getU32("TestSetting") == 13)); - } - - //priorities - template<> template<> - void control_group_t::test<3>() - { - // Pass default_values = true. This tells loadFromFile() we're loading - // a default settings file that declares variables, rather than a user - // settings file. When loadFromFile() encounters an unrecognized user - // settings variable, it forcibly preserves it (CHOP-962). - int results = mCG->loadFromFile(mTestConfigFile.c_str(), true); - LLControlVariable* control = mCG->getControl("TestSetting"); - LLSD new_value = 13; - control->setValue(new_value, false); - ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13); - LLControlGroup test_cg("foo3"); - std::string temp_test_file = (mTestConfigDir + "setting_llsd_persist_temp.xml"); - mCleanups.push_back(temp_test_file); - mCG->saveToFile(temp_test_file.c_str(), true); - results = test_cg.loadFromFile(temp_test_file.c_str()); - //If we haven't changed any settings, then we shouldn't have any settings to load - ensure("number of non-persisted changed settings loaded", (results == 0)); - } - - //listeners - template<> template<> - void control_group_t::test<4>() - { - int results = mCG->loadFromFile(mTestConfigFile.c_str()); - ensure("number of settings", (results == 1)); - mCG->getControl("TestSetting")->getSignal()->connect(boost::bind(&this->handleListenerTest)); - mCG->setU32("TestSetting", 13); - ensure("listener fired on changed setting", mListenerFired); - } - -} +/** + * @file llcontrol_tut.cpp + * @date February 2008 + * @brief control group unit tests + * + * $LicenseInfo:firstyear=2008&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llsdserialize.h" +#include "llfile.h" +#include "stringize.h" + +#include "../llcontrol.h" + +#include "../test/lltut.h" +#include +#include + +namespace tut +{ + struct control_group + { + std::unique_ptr mCG; + std::string mTestConfigDir; + std::string mTestConfigFile; + std::vector mCleanups; + static bool mListenerFired; + control_group() + { + mCG.reset(new LLControlGroup("foo")); + LLUUID random; + random.generate(); + // generate temp dir + mTestConfigDir = STRINGIZE(LLFile::tmpdir() << "llcontrol-test-" << random << "/"); + mTestConfigFile = mTestConfigDir + "settings.xml"; + LLFile::mkdir(mTestConfigDir); + LLSD config; + config["TestSetting"]["Comment"] = "Dummy setting used for testing"; + config["TestSetting"]["Persist"] = 1; + config["TestSetting"]["Type"] = "U32"; + config["TestSetting"]["Value"] = 12; + writeSettingsFile(config); + } + ~control_group() + { + //Remove test files + for (auto filename : mCleanups) + { + LLFile::remove(filename); + } + LLFile::remove(mTestConfigFile); + LLFile::rmdir(mTestConfigDir); + } + void writeSettingsFile(const LLSD& config) + { + llofstream file(mTestConfigFile.c_str()); + if (file.is_open()) + { + LLSDSerialize::toPrettyXML(config, file); + } + file.close(); + } + static bool handleListenerTest() + { + control_group::mListenerFired = true; + return true; + } + }; + + bool control_group::mListenerFired = false; + + typedef test_group control_group_test; + typedef control_group_test::object control_group_t; + control_group_test tut_control_group("control_group"); + + //load settings from files - LLSD + template<> template<> + void control_group_t::test<1>() + { + int results = mCG->loadFromFile(mTestConfigFile.c_str()); + ensure("number of settings", (results == 1)); + ensure("value of setting", (mCG->getU32("TestSetting") == 12)); + } + + //save settings to files + template<> template<> + void control_group_t::test<2>() + { + int results = mCG->loadFromFile(mTestConfigFile.c_str()); + mCG->setU32("TestSetting", 13); + ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13); + LLControlGroup test_cg("foo2"); + std::string temp_test_file = (mTestConfigDir + "setting_llsd_temp.xml"); + mCleanups.push_back(temp_test_file); + mCG->saveToFile(temp_test_file.c_str(), true); + results = test_cg.loadFromFile(temp_test_file.c_str()); + ensure("number of changed settings loaded", (results == 1)); + ensure("value of changed settings loaded", (test_cg.getU32("TestSetting") == 13)); + } + + //priorities + template<> template<> + void control_group_t::test<3>() + { + // Pass default_values = true. This tells loadFromFile() we're loading + // a default settings file that declares variables, rather than a user + // settings file. When loadFromFile() encounters an unrecognized user + // settings variable, it forcibly preserves it (CHOP-962). + int results = mCG->loadFromFile(mTestConfigFile.c_str(), true); + LLControlVariable* control = mCG->getControl("TestSetting"); + LLSD new_value = 13; + control->setValue(new_value, false); + ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13); + LLControlGroup test_cg("foo3"); + std::string temp_test_file = (mTestConfigDir + "setting_llsd_persist_temp.xml"); + mCleanups.push_back(temp_test_file); + mCG->saveToFile(temp_test_file.c_str(), true); + results = test_cg.loadFromFile(temp_test_file.c_str()); + //If we haven't changed any settings, then we shouldn't have any settings to load + ensure("number of non-persisted changed settings loaded", (results == 0)); + } + + //listeners + template<> template<> + void control_group_t::test<4>() + { + int results = mCG->loadFromFile(mTestConfigFile.c_str()); + ensure("number of settings", (results == 1)); + mCG->getControl("TestSetting")->getSignal()->connect(boost::bind(&this->handleListenerTest)); + mCG->setU32("TestSetting", 13); + ensure("listener fired on changed setting", mListenerFired); + } + +} -- cgit v1.2.3 From b42f9d836b4c0f7fbd4bdae1734021e2a09fdbe8 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Sat, 1 Jun 2024 15:49:26 +0200 Subject: Re-enable a lot of compiler warnings for MSVC and address the C4267 "possible loss of precision" warnings --- indra/llxml/llxmlnode.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 5e98af8412..0fd4516844 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -670,7 +670,7 @@ bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXML buffer[nread] = 0; fclose(fp); - bool rv = parseBuffer(buffer, nread, node, defaults_tree); + bool rv = parseBuffer(buffer, static_cast(nread), node, defaults_tree); delete [] buffer; return rv; } @@ -2681,7 +2681,7 @@ U32 LLXMLNode::getChildCount() const { if (mChildren.notNull()) { - return mChildren->map.size(); + return static_cast(mChildren->map.size()); } return 0; } @@ -2700,7 +2700,7 @@ LLXMLNode *get_rand_node(LLXMLNode *node) { if (node->mChildren.notNull()) { - U32 num_children = node->mChildren->map.size(); + U32 num_children = static_cast(node->mChildren->map.size()); if (get_rand(2) == 0) { while (true) -- cgit v1.2.3 From 2ea5ac0c43e3e28d2b1774f5367d099271a1da32 Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Mon, 1 Jul 2024 13:34:50 +0200 Subject: #1111 Remove xmlrpc-epi --- indra/llxml/llxmlnode.cpp | 39 ++++++++++++++++++--------------------- indra/llxml/llxmlnode.h | 12 ++++++------ 2 files changed, 24 insertions(+), 27 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 0fd4516844..7f6b8093fc 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -653,32 +653,24 @@ bool LLXMLNode::updateNode( // static bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXMLNode* defaults_tree) { - // Read file - LL_DEBUGS("XMLNode") << "parsing XML file: " << filename << LL_ENDL; - LLFILE* fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */ - if (fp == NULL) + std::string xml = LLFile::getContents(filename); + if (xml.empty()) { - node = NULL ; - return false; + LL_WARNS("XMLNode") << "no XML file: " << filename << LL_ENDL; + } + else if (parseBuffer(xml.data(), xml.size(), node, defaults_tree)) + { + return true; } - fseek(fp, 0, SEEK_END); - U32 length = ftell(fp); - fseek(fp, 0, SEEK_SET); - - U8* buffer = new U8[length+1]; - size_t nread = fread(buffer, 1, length, fp); - buffer[nread] = 0; - fclose(fp); - bool rv = parseBuffer(buffer, static_cast(nread), node, defaults_tree); - delete [] buffer; - return rv; + node = nullptr; + return false; } // static bool LLXMLNode::parseBuffer( - U8* buffer, - U32 length, + const char* buffer, + U64 length, LLXMLNodePtr& node, LLXMLNode* defaults) { @@ -693,20 +685,25 @@ bool LLXMLNode::parseBuffer( file_node->mParser = &my_parser; - XML_SetUserData(my_parser, (void *)file_node_ptr); + XML_SetUserData(my_parser, file_node_ptr); // Do the parsing - if (XML_Parse(my_parser, (const char *)buffer, length, true) != XML_STATUS_OK) + bool success = XML_STATUS_OK == XML_Parse(my_parser, buffer, (int)length, true); + if (!success) { LL_WARNS() << "Error parsing xml error code: " << XML_ErrorString(XML_GetErrorCode(my_parser)) << " on line " << XML_GetCurrentLineNumber(my_parser) + << ", column " << XML_GetCurrentColumnNumber(my_parser) << LL_ENDL; } // Deinit XML_ParserFree(my_parser); + if (!success) + return false; + if (!file_node->mChildren || file_node->mChildren->map.size() != 1) { LL_WARNS() << "Parse failure - wrong number of top-level nodes xml." diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index b8e29bbfef..b8f9e1ff69 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -129,20 +129,20 @@ public: void addChild(LLXMLNodePtr& new_child); void setParent(LLXMLNodePtr& new_parent); // reparent if necessary - // Serialization + // Deserialization static bool parseFile( const std::string& filename, LLXMLNodePtr& node, - LLXMLNode* defaults_tree); + LLXMLNode* defaults = nullptr); static bool parseBuffer( - U8* buffer, - U32 length, + const char* buffer, + U64 length, LLXMLNodePtr& node, - LLXMLNode* defaults); + LLXMLNode* defaults = nullptr); static bool parseStream( std::istream& str, LLXMLNodePtr& node, - LLXMLNode* defaults); + LLXMLNode* defaults = nullptr); static bool updateNode( LLXMLNodePtr& node, LLXMLNodePtr& update_node); -- cgit v1.2.3 From b0e30477e93bb16b0cf8c7b64aaee35cedf85ca8 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Mon, 1 Jul 2024 22:25:56 -0400 Subject: Use heterogeneous comparison for string_view map finds in LLControl and convert controlExists to string_view --- indra/llxml/llcontrol.cpp | 4 ++-- indra/llxml/llcontrol.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index 82e07e03c9..bb590ebd76 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -348,7 +348,7 @@ LLPointer LLControlGroup::getControl(std::string_view name) incrCount(name); } - ctrl_name_table_t::iterator iter = mNameTable.find(name.data()); + ctrl_name_table_t::iterator iter = mNameTable.find(name); return iter == mNameTable.end() ? LLPointer() : iter->second; } @@ -657,7 +657,7 @@ LLSD LLControlGroup::asLLSD(bool diffs_only) return result; } -bool LLControlGroup::controlExists(const std::string& name) +bool LLControlGroup::controlExists(std::string_view name) { ctrl_name_table_t::iterator iter = mNameTable.find(name); return iter != mNameTable.end(); diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 1b04729a82..344352e980 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -189,7 +189,7 @@ class LLControlGroup : public LLInstanceTracker LOG_CLASS(LLControlGroup); protected: - typedef std::map ctrl_name_table_t; + typedef std::map > ctrl_name_table_t; ctrl_name_table_t mNameTable; static const std::string mTypeString[TYPE_COUNT]; @@ -295,7 +295,7 @@ public: } } - bool controlExists(const std::string& name); + bool controlExists(std::string_view name); // Returns number of controls loaded, 0 if failed // If require_declaration is false, will auto-declare controls it finds -- cgit v1.2.3 From 9a3c770a3bf430da8878a8691cee9b726a5f026c Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 2 Jul 2024 13:12:40 -0400 Subject: Eliminate c_str() calls from LLControlGroup::loadFromFile() calls. Passing std::string::c_str() to a (const std::string&) function parameter is worse than clutter, it's pointless overhead: it forces the compiler to construct a new std::string instance, instead of passing a const reference to the one you already have in hand. --- indra/llxml/tests/llcontrol_test.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/tests/llcontrol_test.cpp b/indra/llxml/tests/llcontrol_test.cpp index f5f8b285f7..595c6a600b 100644 --- a/indra/llxml/tests/llcontrol_test.cpp +++ b/indra/llxml/tests/llcontrol_test.cpp @@ -97,7 +97,7 @@ namespace tut template<> template<> void control_group_t::test<1>() { - int results = mCG->loadFromFile(mTestConfigFile.c_str()); + int results = mCG->loadFromFile(mTestConfigFile); ensure("number of settings", (results == 1)); ensure("value of setting", (mCG->getU32("TestSetting") == 12)); } @@ -106,14 +106,14 @@ namespace tut template<> template<> void control_group_t::test<2>() { - int results = mCG->loadFromFile(mTestConfigFile.c_str()); + int results = mCG->loadFromFile(mTestConfigFile); mCG->setU32("TestSetting", 13); ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13); LLControlGroup test_cg("foo2"); std::string temp_test_file = (mTestConfigDir + "setting_llsd_temp.xml"); mCleanups.push_back(temp_test_file); mCG->saveToFile(temp_test_file.c_str(), TRUE); - results = test_cg.loadFromFile(temp_test_file.c_str()); + results = test_cg.loadFromFile(temp_test_file); ensure("number of changed settings loaded", (results == 1)); ensure("value of changed settings loaded", (test_cg.getU32("TestSetting") == 13)); } @@ -126,7 +126,7 @@ namespace tut // a default settings file that declares variables, rather than a user // settings file. When loadFromFile() encounters an unrecognized user // settings variable, it forcibly preserves it (CHOP-962). - int results = mCG->loadFromFile(mTestConfigFile.c_str(), true); + int results = mCG->loadFromFile(mTestConfigFile, true); LLControlVariable* control = mCG->getControl("TestSetting"); LLSD new_value = 13; control->setValue(new_value, FALSE); @@ -135,7 +135,7 @@ namespace tut std::string temp_test_file = (mTestConfigDir + "setting_llsd_persist_temp.xml"); mCleanups.push_back(temp_test_file); mCG->saveToFile(temp_test_file.c_str(), TRUE); - results = test_cg.loadFromFile(temp_test_file.c_str()); + results = test_cg.loadFromFile(temp_test_file); //If we haven't changed any settings, then we shouldn't have any settings to load ensure("number of non-persisted changed settings loaded", (results == 0)); } @@ -144,7 +144,7 @@ namespace tut template<> template<> void control_group_t::test<4>() { - int results = mCG->loadFromFile(mTestConfigFile.c_str()); + int results = mCG->loadFromFile(mTestConfigFile); ensure("number of settings", (results == 1)); mCG->getControl("TestSetting")->getSignal()->connect(boost::bind(&this->handleListenerTest)); mCG->setU32("TestSetting", 13); -- cgit v1.2.3 From 989cfe2f70441fe02222d369e84118a94dc96890 Mon Sep 17 00:00:00 2001 From: Henri Beauchamp Date: Mon, 8 Jul 2024 23:18:02 +0200 Subject: Fix for crash in XMLRPC reply decoding on login with large inventories Commit 2ea5ac0c43e3e28d2b1774f5367d099271a1da32 introduced a crash bug due to the recursive construction of the XMLTreeNode wrapper class. The constructor of the said class typically recurses twice as many times as there are entries in the user's inventory list. This commit: - Moves the fromXMLRPCValue() method and its helper functions from the LLSD class/module to the LLXMLNode class, where it belongs, thus making LLSD::TreeNode (which was a wrapper class to avoid making llcommon dependant on llxml, which is still the case after this commit) totally moot; the fromXMLRPCValue() call is now done directly on the LLXMLNode. - Moves the XML and XMLRPC decoding code out of the HTTP coroutine LLXMLRPCTransaction::Handler (coroutines got an even smaller and fixed stack), and into LLXMLRPCTransaction::Impl::process(). - Removes XMLTreeNode entirely, fixing the crash as a result. --- indra/llxml/llxmlnode.cpp | 172 ++++++++++++++++++++++++++++++++++++++++++++++ indra/llxml/llxmlnode.h | 9 ++- 2 files changed, 179 insertions(+), 2 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 7f6b8093fc..8eb4556828 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -38,7 +38,9 @@ #include "v3math.h" #include "v3dmath.h" #include "v4math.h" +#include "llbase64.h" #include "llquaternion.h" +#include "llsd.h" #include "llstring.h" #include "lluuid.h" #include "lldir.h" @@ -3263,3 +3265,173 @@ S32 LLXMLNode::getLineNumber() { return mLineNumber; } + +bool LLXMLNode::parseXmlRpcArrayValue(LLSD& target) +{ + LLXMLNode* datap = getFirstChild().get(); + if (!datap) + { + LL_WARNS() << "No inner XML element." << LL_ENDL; + return false; + } + if (!datap->hasName("data")) + { + LL_WARNS() << "No inner XML element ( expected, got: " + << datap->mName->mString << ")" << LL_ENDL; + return false; + } + if (datap->getNextSibling().get()) + { + LL_WARNS() << "Multiple inner XML elements (single expected)" + << LL_ENDL; + return false; + } + U32 i = 0; + for (LLXMLNode* itemp = datap->getFirstChild().get(); itemp; + itemp = itemp->getNextSibling().get()) + { + LLSD value; + if (!itemp->fromXMLRPCValue(value)) + { + return false; + } + target.append(value); + ++i; + } + return true; +} + +bool LLXMLNode::parseXmlRpcStructValue(LLSD& target) +{ + std::string name; + LLSD value; + for (LLXMLNode* itemp = getFirstChild().get(); itemp; + itemp = itemp->getNextSibling().get()) + { + if (!itemp->hasName("member")) + { + LL_WARNS() << "Invalid inner XML element ( expected, got: <" + << itemp->mName->mString << ">" << LL_ENDL; + return false; + } + name.clear(); + value.clear(); + for (LLXMLNode* chilp = itemp->getFirstChild().get(); chilp; + chilp = chilp->getNextSibling().get()) + { + if (chilp->hasName("name")) + { + name = LLStringFn::xml_decode(chilp->getTextContents()); + } + else if (!chilp->fromXMLRPCValue(value)) + { + return false; + } + } + if (name.empty()) + { + LL_WARNS() << "Empty struct member name" << LL_ENDL; + return false; + } + target.insert(name, value); + } + return true; +} + +bool LLXMLNode::fromXMLRPCValue(LLSD& target) +{ + target.clear(); + + if (!hasName("value")) + { + LL_WARNS() << "Invalid XML element ( expected), got: <" + << mName->mString << ">" << LL_ENDL; + return false; + } + + LLXMLNode* childp = getFirstChild().get(); + if (!childp) + { + LL_WARNS() << "No inner XML element (value type expected)" << LL_ENDL; + // Value with no type qualifier is treated as string + target.assign(LLStringFn::xml_decode(getTextContents())); + return true; + } + + if (childp->getNextSibling()) + { + LL_WARNS() << "Multiple inner XML elements (single expected)" + << LL_ENDL; + return false; + } + + if (childp->hasName("string")) + { + target.assign(LLStringFn::xml_decode(childp->getTextContents())); + return true; + } + + if (childp->hasName("int") || childp->hasName("i4")) + { + target.assign(std::stoi(childp->getTextContents())); + return true; + } + + if (childp->hasName("double")) + { + target.assign(std::stod(childp->getTextContents())); + return true; + } + + if (childp->hasName("boolean")) + { + target.assign(std::stoi(childp->getTextContents()) != 0); + return true; + } + + if (childp->hasName("dateTime.iso8601")) + { + target.assign(LLSD::Date(childp->getTextContents())); + return true; + } + + if (childp->hasName("base64")) + { + std::string decoded = + LLBase64::decodeAsString(inner->getTextContents()); + size_t size = decoded.size(); + LLSD::Binary binary(size); + if (size) + { + memcpy((void*)binary.data(), (void*)decoded.data(), size); + } + target.assign(binary); + return true; + } + + if (childp->hasName("array")) + { + if (!childp->parseXmlRpcArrayValue(target)) + { + target.clear(); + return false; + } + return true; + } + + if (childp->hasName("struct")) + { + if (!childp->parseXmlRpcStructValue(target)) + { + target.clear(); + return false; + } + return true; + } + + LL_WARNS() << "Unknown inner XML element (known value type expected)" + << LL_ENDL; + // Value with unknown type qualifier is treated as string + target.assign(LLStringFn::xml_decode(childp->getTextContents())); + return true; +} diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index b8f9e1ff69..3769ec8293 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -50,6 +50,7 @@ class LLVector3d; class LLQuaternion; class LLColor4; class LLColor4U; +class LLSD; struct CompareAttributes @@ -284,12 +285,18 @@ public: void setAttributes(ValueType type, U32 precision, Encoding encoding, U32 length); // void appendValue(const std::string& value); // Unused + bool fromXMLRPCValue(LLSD& target); + // Unit Testing void createUnitTest(S32 max_num_children); bool performUnitTest(std::string &error_buffer); protected: bool removeChild(LLXMLNode* child); + bool isFullyDefault(); + + bool parseXmlRpcArrayValue(LLSD& target); + bool parseXmlRpcStructValue(LLSD& target); public: std::string mID; // The ID attribute of this node @@ -328,8 +335,6 @@ protected: static const char *skipNonWhitespace(const char *str); static const char *parseInteger(const char *str, U64 *dest, bool *is_negative, U32 precision, Encoding encoding); static const char *parseFloat(const char *str, F64 *dest, U32 precision, Encoding encoding); - - bool isFullyDefault(); }; #endif // LL_LLXMLNODE -- cgit v1.2.3 From 0df35799a39b8a76d13ccb4c1ab4d57a0ab6d129 Mon Sep 17 00:00:00 2001 From: Henri Beauchamp Date: Mon, 8 Jul 2024 23:31:43 +0200 Subject: Remove a remnant of debug code. --- indra/llxml/llxmlnode.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 8eb4556828..d6f9a56c9d 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -3286,7 +3286,6 @@ bool LLXMLNode::parseXmlRpcArrayValue(LLSD& target) << LL_ENDL; return false; } - U32 i = 0; for (LLXMLNode* itemp = datap->getFirstChild().get(); itemp; itemp = itemp->getNextSibling().get()) { @@ -3296,7 +3295,6 @@ bool LLXMLNode::parseXmlRpcArrayValue(LLSD& target) return false; } target.append(value); - ++i; } return true; } -- cgit v1.2.3 From 89c1767bd38ae97c9ca3ba120d8d5c0f94373c1b Mon Sep 17 00:00:00 2001 From: Ansariel Date: Tue, 9 Jul 2024 02:59:49 +0200 Subject: Fix build error in llxmlnode.cpp --- indra/llxml/llxmlnode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index d6f9a56c9d..e695035461 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -3396,7 +3396,7 @@ bool LLXMLNode::fromXMLRPCValue(LLSD& target) if (childp->hasName("base64")) { std::string decoded = - LLBase64::decodeAsString(inner->getTextContents()); + LLBase64::decodeAsString(childp->getTextContents()); size_t size = decoded.size(); LLSD::Binary binary(size); if (size) -- cgit v1.2.3 From 34cc2de079db3a267e0880c04b6b4c14611a5403 Mon Sep 17 00:00:00 2001 From: Zi Ree <81702435+zi-ree@users.noreply.github.com> Date: Mon, 29 Jul 2024 18:20:25 +0200 Subject: fix another misleading indentation compiler warning Fix indentation mistake that trips gcc's misleading indentation warning. --- indra/llxml/llxmltree.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llxmltree.cpp b/indra/llxml/llxmltree.cpp index 0ace1baf2a..164b3156e1 100644 --- a/indra/llxml/llxmltree.cpp +++ b/indra/llxml/llxmltree.cpp @@ -111,11 +111,11 @@ LLXmlTreeNode::~LLXmlTreeNode() attribute_map_t::iterator iter; for (iter=mAttributes.begin(); iter != mAttributes.end(); iter++) delete iter->second; - for(LLXmlTreeNode* node : mChildren) - { - delete node; - } - mChildren.clear(); + for(LLXmlTreeNode* node : mChildren) + { + delete node; + } + mChildren.clear(); } void LLXmlTreeNode::dump( const std::string& prefix ) -- cgit v1.2.3 From b5e306f7d89e82984a37824a3640bd67a5c45d61 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Wed, 14 Aug 2024 11:01:02 -0400 Subject: Enable /permissive- on MSVC for better standards conformance (#2251) * Enable /permissive- on MSVC for better C++ conformance and fix related errors * Clean up left over warning suppressions from old library or msvc versions --- indra/llxml/llcontrol.h | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 344352e980..4f54a9d705 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -36,32 +36,8 @@ #include -// *NOTE: boost::visit_each<> generates warning 4675 on .net 2003 -// Disable the warning for the boost includes. -#if LL_WINDOWS -# if (_MSC_VER >= 1300 && _MSC_VER < 1400) -# pragma warning(push) -# pragma warning( disable : 4675 ) -# endif -#endif - #include - -#if LL_WINDOWS - #pragma warning (push) - #pragma warning (disable : 4263) // boost::signals2::expired_slot::what() has const mismatch - #pragma warning (disable : 4264) -#endif #include -#if LL_WINDOWS - #pragma warning (pop) -#endif - -#if LL_WINDOWS -# if (_MSC_VER >= 1300 && _MSC_VER < 1400) -# pragma warning(pop) -# endif -#endif class LLVector3; class LLVector3d; -- cgit v1.2.3 From c4f29a535359fe1ecdb8bec45596f40b02891cd1 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 4 Sep 2024 14:17:32 -0400 Subject: Resolve a few unresolved merge conflicts. --- indra/llxml/tests/llcontrol_test.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/tests/llcontrol_test.cpp b/indra/llxml/tests/llcontrol_test.cpp index 4cb66a91fb..52c202bceb 100644 --- a/indra/llxml/tests/llcontrol_test.cpp +++ b/indra/llxml/tests/llcontrol_test.cpp @@ -134,16 +134,8 @@ namespace tut LLControlGroup test_cg("foo3"); std::string temp_test_file = (mTestConfigDir + "setting_llsd_persist_temp.xml"); mCleanups.push_back(temp_test_file); -<<<<<<< variant A - mCG->saveToFile(temp_test_file.c_str(), TRUE); - results = test_cg.loadFromFile(temp_test_file); ->>>>>>> variant B mCG->saveToFile(temp_test_file.c_str(), true); - results = test_cg.loadFromFile(temp_test_file.c_str()); -####### Ancestor - mCG->saveToFile(temp_test_file.c_str(), TRUE); - results = test_cg.loadFromFile(temp_test_file.c_str()); -======= end + results = test_cg.loadFromFile(temp_test_file); //If we haven't changed any settings, then we shouldn't have any settings to load ensure("number of non-persisted changed settings loaded", (results == 0)); } -- cgit v1.2.3