diff options
Diffstat (limited to 'indra/llxml')
-rw-r--r-- | indra/llxml/llcontrol.cpp | 4 | ||||
-rw-r--r-- | indra/llxml/llcontrol.h | 4 | ||||
-rw-r--r-- | indra/llxml/llxmlnode.cpp | 170 | ||||
-rw-r--r-- | indra/llxml/llxmlnode.h | 9 |
4 files changed, 181 insertions, 6 deletions
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<LLControlVariable> 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<LLControlVariable>() : 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<LLControlGroup, std::string> LOG_CLASS(LLControlGroup); protected: - typedef std::map<std::string, LLControlVariablePtr > ctrl_name_table_t; + typedef std::map<std::string, LLControlVariablePtr, std::less<> > 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 diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 7f6b8093fc..e695035461 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,171 @@ 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 (<data> expected, got: " + << datap->mName->mString << ")" << LL_ENDL; + return false; + } + if (datap->getNextSibling().get()) + { + LL_WARNS() << "Multiple inner XML elements (single <data> expected)" + << LL_ENDL; + return false; + } + for (LLXMLNode* itemp = datap->getFirstChild().get(); itemp; + itemp = itemp->getNextSibling().get()) + { + LLSD value; + if (!itemp->fromXMLRPCValue(value)) + { + return false; + } + target.append(value); + } + 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 (<member> 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 (<value> 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(childp->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 |