diff options
Diffstat (limited to 'linden/indra/llxml')
-rw-r--r-- | linden/indra/llxml/CMakeLists.txt | 1 | ||||
-rw-r--r-- | linden/indra/llxml/llcontrol.cpp | 56 | ||||
-rw-r--r-- | linden/indra/llxml/llcontrol.h | 16 | ||||
-rw-r--r-- | linden/indra/llxml/llcontrolgroupreader.h | 74 | ||||
-rw-r--r-- | linden/indra/llxml/llxmlnode.cpp | 188 | ||||
-rw-r--r-- | linden/indra/llxml/llxmlnode.h | 29 | ||||
-rw-r--r-- | linden/indra/llxml/llxmlparser.cpp | 3 | ||||
-rw-r--r-- | linden/indra/llxml/llxmlparser.h | 3 | ||||
-rw-r--r-- | linden/indra/llxml/llxmltree.cpp | 3 | ||||
-rw-r--r-- | linden/indra/llxml/llxmltree.h | 3 |
10 files changed, 317 insertions, 59 deletions
diff --git a/linden/indra/llxml/CMakeLists.txt b/linden/indra/llxml/CMakeLists.txt index 9febd97..487c5b9 100644 --- a/linden/indra/llxml/CMakeLists.txt +++ b/linden/indra/llxml/CMakeLists.txt | |||
@@ -23,6 +23,7 @@ set(llxml_HEADER_FILES | |||
23 | CMakeLists.txt | 23 | CMakeLists.txt |
24 | 24 | ||
25 | llcontrol.h | 25 | llcontrol.h |
26 | llcontrolgroupreader.h | ||
26 | llxmlnode.h | 27 | llxmlnode.h |
27 | llxmlparser.h | 28 | llxmlparser.h |
28 | llxmltree.h | 29 | llxmltree.h |
diff --git a/linden/indra/llxml/llcontrol.cpp b/linden/indra/llxml/llcontrol.cpp index 81c3e78..d9ed45a 100644 --- a/linden/indra/llxml/llcontrol.cpp +++ b/linden/indra/llxml/llcontrol.cpp | |||
@@ -17,7 +17,8 @@ | |||
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | 20 | * online at |
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | 22 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
@@ -101,11 +102,12 @@ bool LLControlVariable::llsd_compare(const LLSD& a, const LLSD & b) | |||
101 | 102 | ||
102 | LLControlVariable::LLControlVariable(const std::string& name, eControlType type, | 103 | LLControlVariable::LLControlVariable(const std::string& name, eControlType type, |
103 | LLSD initial, const std::string& comment, | 104 | LLSD initial, const std::string& comment, |
104 | bool persist) | 105 | bool persist, bool hidefromsettingseditor) |
105 | : mName(name), | 106 | : mName(name), |
106 | mComment(comment), | 107 | mComment(comment), |
107 | mType(type), | 108 | mType(type), |
108 | mPersist(persist) | 109 | mPersist(persist), |
110 | mHideFromSettingsEditor(hidefromsettingseditor) | ||
109 | { | 111 | { |
110 | if (mPersist && mComment.empty()) | 112 | if (mPersist && mComment.empty()) |
111 | { | 113 | { |
@@ -212,6 +214,11 @@ void LLControlVariable::setPersist(bool state) | |||
212 | mPersist = state; | 214 | mPersist = state; |
213 | } | 215 | } |
214 | 216 | ||
217 | void LLControlVariable::setHiddenFromSettingsEditor(bool hide) | ||
218 | { | ||
219 | mHideFromSettingsEditor = hide; | ||
220 | } | ||
221 | |||
215 | void LLControlVariable::setComment(const std::string& comment) | 222 | void LLControlVariable::setComment(const std::string& comment) |
216 | { | 223 | { |
217 | mComment = comment; | 224 | mComment = comment; |
@@ -295,17 +302,27 @@ std::string LLControlGroup::typeEnumToString(eControlType typeenum) | |||
295 | return mTypeString[typeenum]; | 302 | return mTypeString[typeenum]; |
296 | } | 303 | } |
297 | 304 | ||
298 | BOOL LLControlGroup::declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, BOOL persist) | 305 | BOOL LLControlGroup::declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, BOOL persist, BOOL hidefromsettingseditor) |
299 | { | 306 | { |
300 | if(mNameTable.find(name) != mNameTable.end()) | 307 | LLControlVariable* existing_control = getControl(name); |
301 | { | 308 | if (existing_control) |
302 | llwarns << "LLControlGroup::declareControl: Control named " << name << " already exists." << llendl; | 309 | { |
303 | mNameTable[name]->setValue(initial_val); | 310 | if (persist && existing_control->isType(type)) |
304 | return TRUE; | 311 | { |
312 | // Sometimes we need to declare a control *after* it has been loaded from a settings file. | ||
313 | LLSD cur_value = existing_control->getValue(); // get the current value | ||
314 | existing_control->setDefaultValue(initial_val); // set the default to the declared value | ||
315 | existing_control->setValue(cur_value); // now set to the loaded value | ||
316 | } | ||
317 | else | ||
318 | { | ||
319 | llwarns << "Control named " << name << " already exists, ignoring new declaration." << llendl; | ||
320 | } | ||
321 | return TRUE; | ||
305 | } | 322 | } |
306 | 323 | ||
307 | // if not, create the control and add it to the name table | 324 | // if not, create the control and add it to the name table |
308 | LLControlVariable* control = new LLControlVariable(name, type, initial_val, comment, persist); | 325 | LLControlVariable* control = new LLControlVariable(name, type, initial_val, comment, persist, hidefromsettingseditor); |
309 | mNameTable[name] = control; | 326 | mNameTable[name] = control; |
310 | return TRUE; | 327 | return TRUE; |
311 | } | 328 | } |
@@ -1042,7 +1059,8 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v | |||
1042 | } | 1059 | } |
1043 | 1060 | ||
1044 | U32 validitems = 0; | 1061 | U32 validitems = 0; |
1045 | bool persist = false; | 1062 | bool persist = true; |
1063 | bool hidefromsettingseditor = false; | ||
1046 | for(LLSD::map_const_iterator itr = settings.beginMap(); itr != settings.endMap(); ++itr) | 1064 | for(LLSD::map_const_iterator itr = settings.beginMap(); itr != settings.endMap(); ++itr) |
1047 | { | 1065 | { |
1048 | name = (*itr).first; | 1066 | name = (*itr).first; |
@@ -1053,6 +1071,18 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v | |||
1053 | persist = control_map["Persist"].asInteger(); | 1071 | persist = control_map["Persist"].asInteger(); |
1054 | } | 1072 | } |
1055 | 1073 | ||
1074 | // Sometimes we want to use the settings system to provide cheap persistence, but we | ||
1075 | // don't want the settings themselves to be easily manipulated in the UI because | ||
1076 | // doing so can cause support problems. So we have this option: | ||
1077 | if(control_map.has("HideFromEditor")) | ||
1078 | { | ||
1079 | hidefromsettingseditor = control_map["HideFromEditor"].asInteger(); | ||
1080 | } | ||
1081 | else | ||
1082 | { | ||
1083 | hidefromsettingseditor = false; | ||
1084 | } | ||
1085 | |||
1056 | // If the control exists just set the value from the input file. | 1086 | // If the control exists just set the value from the input file. |
1057 | LLControlVariable* existing_control = getControl(name); | 1087 | LLControlVariable* existing_control = getControl(name); |
1058 | if(existing_control) | 1088 | if(existing_control) |
@@ -1066,6 +1096,7 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v | |||
1066 | { | 1096 | { |
1067 | existing_control->setDefaultValue(control_map["Value"]); | 1097 | existing_control->setDefaultValue(control_map["Value"]); |
1068 | existing_control->setPersist(persist); | 1098 | existing_control->setPersist(persist); |
1099 | existing_control->setHiddenFromSettingsEditor(hidefromsettingseditor); | ||
1069 | existing_control->setComment(control_map["Comment"].asString()); | 1100 | existing_control->setComment(control_map["Comment"].asString()); |
1070 | } | 1101 | } |
1071 | else | 1102 | else |
@@ -1089,7 +1120,8 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v | |||
1089 | typeStringToEnum(control_map["Type"].asString()), | 1120 | typeStringToEnum(control_map["Type"].asString()), |
1090 | control_map["Value"], | 1121 | control_map["Value"], |
1091 | control_map["Comment"].asString(), | 1122 | control_map["Comment"].asString(), |
1092 | persist | 1123 | persist, |
1124 | hidefromsettingseditor | ||
1093 | ); | 1125 | ); |
1094 | } | 1126 | } |
1095 | 1127 | ||
diff --git a/linden/indra/llxml/llcontrol.h b/linden/indra/llxml/llcontrol.h index 7b327ef..ba0a1c7 100644 --- a/linden/indra/llxml/llcontrol.h +++ b/linden/indra/llxml/llcontrol.h | |||
@@ -17,7 +17,8 @@ | |||
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | 20 | * online at |
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | 22 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
@@ -38,6 +39,8 @@ | |||
38 | #include "llstring.h" | 39 | #include "llstring.h" |
39 | #include "llrect.h" | 40 | #include "llrect.h" |
40 | 41 | ||
42 | #include "llcontrolgroupreader.h" | ||
43 | |||
41 | #include <vector> | 44 | #include <vector> |
42 | 45 | ||
43 | // *NOTE: boost::visit_each<> generates warning 4675 on .net 2003 | 46 | // *NOTE: boost::visit_each<> generates warning 4675 on .net 2003 |
@@ -92,7 +95,8 @@ private: | |||
92 | std::string mName; | 95 | std::string mName; |
93 | std::string mComment; | 96 | std::string mComment; |
94 | eControlType mType; | 97 | eControlType mType; |
95 | bool mPersist; | 98 | bool mPersist; |
99 | bool mHideFromSettingsEditor; | ||
96 | std::vector<LLSD> mValues; | 100 | std::vector<LLSD> mValues; |
97 | 101 | ||
98 | signal_t mSignal; | 102 | signal_t mSignal; |
@@ -100,7 +104,7 @@ private: | |||
100 | public: | 104 | public: |
101 | LLControlVariable(const std::string& name, eControlType type, | 105 | LLControlVariable(const std::string& name, eControlType type, |
102 | LLSD initial, const std::string& comment, | 106 | LLSD initial, const std::string& comment, |
103 | bool persist = true); | 107 | bool persist = true, bool hidefromsettingseditor = false); |
104 | 108 | ||
105 | virtual ~LLControlVariable(); | 109 | virtual ~LLControlVariable(); |
106 | 110 | ||
@@ -117,6 +121,7 @@ public: | |||
117 | bool isDefault() { return (mValues.size() == 1); } | 121 | bool isDefault() { return (mValues.size() == 1); } |
118 | bool isSaveValueDefault(); | 122 | bool isSaveValueDefault(); |
119 | bool isPersisted() { return mPersist; } | 123 | bool isPersisted() { return mPersist; } |
124 | bool isHiddenFromSettingsEditor() { return mHideFromSettingsEditor; } | ||
120 | LLSD get() const { return getValue(); } | 125 | LLSD get() const { return getValue(); } |
121 | LLSD getValue() const { return mValues.back(); } | 126 | LLSD getValue() const { return mValues.back(); } |
122 | LLSD getDefault() const { return mValues.front(); } | 127 | LLSD getDefault() const { return mValues.front(); } |
@@ -126,6 +131,7 @@ public: | |||
126 | void setValue(const LLSD& value, bool saved_value = TRUE); | 131 | void setValue(const LLSD& value, bool saved_value = TRUE); |
127 | void setDefaultValue(const LLSD& value); | 132 | void setDefaultValue(const LLSD& value); |
128 | void setPersist(bool state); | 133 | void setPersist(bool state); |
134 | void setHiddenFromSettingsEditor(bool hide); | ||
129 | void setComment(const std::string& comment); | 135 | void setComment(const std::string& comment); |
130 | 136 | ||
131 | void firePropertyChanged() | 137 | void firePropertyChanged() |
@@ -139,7 +145,7 @@ private: | |||
139 | }; | 145 | }; |
140 | 146 | ||
141 | //const U32 STRING_CACHE_SIZE = 10000; | 147 | //const U32 STRING_CACHE_SIZE = 10000; |
142 | class LLControlGroup | 148 | class LLControlGroup : public LLControlGroupReader |
143 | { | 149 | { |
144 | protected: | 150 | protected: |
145 | typedef std::map<std::string, LLPointer<LLControlVariable> > ctrl_name_table_t; | 151 | typedef std::map<std::string, LLPointer<LLControlVariable> > ctrl_name_table_t; |
@@ -163,7 +169,7 @@ public: | |||
163 | }; | 169 | }; |
164 | void applyToAll(ApplyFunctor* func); | 170 | void applyToAll(ApplyFunctor* func); |
165 | 171 | ||
166 | BOOL declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, BOOL persist); | 172 | BOOL declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, BOOL persist, BOOL hidefromsettingseditor = FALSE); |
167 | BOOL declareU32(const std::string& name, U32 initial_val, const std::string& comment, BOOL persist = TRUE); | 173 | BOOL declareU32(const std::string& name, U32 initial_val, const std::string& comment, BOOL persist = TRUE); |
168 | BOOL declareS32(const std::string& name, S32 initial_val, const std::string& comment, BOOL persist = TRUE); | 174 | BOOL declareS32(const std::string& name, S32 initial_val, const std::string& comment, BOOL persist = TRUE); |
169 | BOOL declareF32(const std::string& name, F32 initial_val, const std::string& comment, BOOL persist = TRUE); | 175 | BOOL declareF32(const std::string& name, F32 initial_val, const std::string& comment, BOOL persist = TRUE); |
diff --git a/linden/indra/llxml/llcontrolgroupreader.h b/linden/indra/llxml/llcontrolgroupreader.h new file mode 100644 index 0000000..c4c04b9 --- /dev/null +++ b/linden/indra/llxml/llcontrolgroupreader.h | |||
@@ -0,0 +1,74 @@ | |||
1 | /** | ||
2 | * @file llcontrolgroupreader.h | ||
3 | * @brief Interface providing readonly access to LLControlGroup (intended for unit testing) | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2001&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2001-2009, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at | ||
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
22 | * | ||
23 | * By copying, modifying or distributing this software, you acknowledge | ||
24 | * that you have read and understood your obligations described above, | ||
25 | * and agree to abide by those obligations. | ||
26 | * | ||
27 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
28 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
29 | * COMPLETENESS OR PERFORMANCE. | ||
30 | * $/LicenseInfo$ | ||
31 | */ | ||
32 | |||
33 | #ifndef LL_LLCONTROLGROUPREADER_H | ||
34 | #define LL_LLCONTROLGROUPREADER_H | ||
35 | |||
36 | #include "stdtypes.h" | ||
37 | #include <string> | ||
38 | |||
39 | // Many of the types below are commented out because for the purposes of the early testing we're doing, | ||
40 | // we don't need them and we don't want to pull in all the machinery to support them. | ||
41 | // But the model is here for future unit test extensions. | ||
42 | |||
43 | class LLControlGroupReader | ||
44 | { | ||
45 | public: | ||
46 | LLControlGroupReader() {} | ||
47 | virtual ~LLControlGroupReader() {} | ||
48 | |||
49 | virtual std::string getString(const std::string& name) = 0; | ||
50 | //virtual LLWString getWString(const std::string& name) = 0; | ||
51 | virtual std::string getText(const std::string& name) = 0; | ||
52 | //virtual LLVector3 getVector3(const std::string& name) = 0; | ||
53 | //virtual LLVector3d getVector3d(const std::string& name) = 0; | ||
54 | //virtual LLRect getRect(const std::string& name) = 0; | ||
55 | virtual BOOL getBOOL(const std::string& name) = 0; | ||
56 | virtual S32 getS32(const std::string& name) = 0; | ||
57 | virtual F32 getF32(const std::string& name) = 0; | ||
58 | virtual U32 getU32(const std::string& name) = 0; | ||
59 | //virtual LLSD getLLSD(const std::string& name) = 0; | ||
60 | |||
61 | //virtual LLColor4 getColor(const std::string& name) = 0; | ||
62 | //virtual LLColor4U getColor4U(const std::string& name) = 0; | ||
63 | //virtual LLColor4 getColor4(const std::string& name) = 0; | ||
64 | //virtual LLColor3 getColor3(const std::string& name) = 0; | ||
65 | }; | ||
66 | |||
67 | #endif /* LL_LLCONTROLGROUPREADER_H */ | ||
68 | |||
69 | |||
70 | |||
71 | |||
72 | |||
73 | |||
74 | |||
diff --git a/linden/indra/llxml/llxmlnode.cpp b/linden/indra/llxml/llxmlnode.cpp index 7464529..800b135 100644 --- a/linden/indra/llxml/llxmlnode.cpp +++ b/linden/indra/llxml/llxmlnode.cpp | |||
@@ -18,7 +18,8 @@ | |||
18 | * There are special exceptions to the terms and conditions of the GPL as | 18 | * There are special exceptions to the terms and conditions of the GPL as |
19 | * it is applied to this Source Code. View the full text of the exception | 19 | * it is applied to this Source Code. View the full text of the exception |
20 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 20 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
21 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | 21 | * online at |
22 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
22 | * | 23 | * |
23 | * By copying, modifying or distributing this software, you acknowledge | 24 | * By copying, modifying or distributing this software, you acknowledge |
24 | * that you have read and understood your obligations described above, | 25 | * that you have read and understood your obligations described above, |
@@ -65,6 +66,9 @@ LLXMLNode::LLXMLNode() : | |||
65 | mEncoding(ENCODING_DEFAULT), | 66 | mEncoding(ENCODING_DEFAULT), |
66 | mParent(NULL), | 67 | mParent(NULL), |
67 | mChildren(NULL), | 68 | mChildren(NULL), |
69 | mAttributes(), | ||
70 | mPrev(NULL), | ||
71 | mNext(NULL), | ||
68 | mName(NULL), | 72 | mName(NULL), |
69 | mValue(""), | 73 | mValue(""), |
70 | mDefault(NULL) | 74 | mDefault(NULL) |
@@ -83,6 +87,9 @@ LLXMLNode::LLXMLNode(const char* name, BOOL is_attribute) : | |||
83 | mEncoding(ENCODING_DEFAULT), | 87 | mEncoding(ENCODING_DEFAULT), |
84 | mParent(NULL), | 88 | mParent(NULL), |
85 | mChildren(NULL), | 89 | mChildren(NULL), |
90 | mAttributes(), | ||
91 | mPrev(NULL), | ||
92 | mNext(NULL), | ||
86 | mValue(""), | 93 | mValue(""), |
87 | mDefault(NULL) | 94 | mDefault(NULL) |
88 | { | 95 | { |
@@ -101,17 +108,65 @@ LLXMLNode::LLXMLNode(LLStringTableEntry* name, BOOL is_attribute) : | |||
101 | mEncoding(ENCODING_DEFAULT), | 108 | mEncoding(ENCODING_DEFAULT), |
102 | mParent(NULL), | 109 | mParent(NULL), |
103 | mChildren(NULL), | 110 | mChildren(NULL), |
111 | mAttributes(), | ||
112 | mPrev(NULL), | ||
113 | mNext(NULL), | ||
104 | mName(name), | 114 | mName(name), |
105 | mValue(""), | 115 | mValue(""), |
106 | mDefault(NULL) | 116 | mDefault(NULL) |
107 | { | 117 | { |
108 | } | 118 | } |
109 | 119 | ||
120 | // copy constructor (except for the children) | ||
121 | LLXMLNode::LLXMLNode(const LLXMLNode& rhs) : | ||
122 | mID(rhs.mID), | ||
123 | mIsAttribute(rhs.mIsAttribute), | ||
124 | mVersionMajor(rhs.mVersionMajor), | ||
125 | mVersionMinor(rhs.mVersionMinor), | ||
126 | mLength(rhs.mLength), | ||
127 | mPrecision(rhs.mPrecision), | ||
128 | mType(rhs.mType), | ||
129 | mEncoding(rhs.mEncoding), | ||
130 | mParent(NULL), | ||
131 | mChildren(NULL), | ||
132 | mAttributes(), | ||
133 | mPrev(NULL), | ||
134 | mNext(NULL), | ||
135 | mName(rhs.mName), | ||
136 | mValue(rhs.mValue), | ||
137 | mDefault(rhs.mDefault) | ||
138 | { | ||
139 | } | ||
140 | |||
141 | // returns a new copy of this node and all its children | ||
142 | LLXMLNodePtr LLXMLNode::deepCopy() | ||
143 | { | ||
144 | LLXMLNodePtr newnode = LLXMLNodePtr(new LLXMLNode(*this)); | ||
145 | if (mChildren.notNull()) | ||
146 | { | ||
147 | for (LLXMLChildList::iterator iter = mChildren->map.begin(); | ||
148 | iter != mChildren->map.end(); ++iter) | ||
149 | { | ||
150 | newnode->addChild(iter->second->deepCopy()); | ||
151 | } | ||
152 | } | ||
153 | for (LLXMLAttribList::iterator iter = mAttributes.begin(); | ||
154 | iter != mAttributes.end(); ++iter) | ||
155 | { | ||
156 | newnode->addChild(iter->second->deepCopy()); | ||
157 | } | ||
158 | |||
159 | return newnode; | ||
160 | } | ||
161 | |||
110 | // virtual | 162 | // virtual |
111 | LLXMLNode::~LLXMLNode() | 163 | LLXMLNode::~LLXMLNode() |
112 | { | 164 | { |
113 | // Strictly speaking none of this should be required execept 'delete mChildren'... | 165 | // Strictly speaking none of this should be required execept 'delete mChildren'... |
114 | if (mChildren) | 166 | // Sadly, that's only true if we hadn't had reference-counted smart pointers linked |
167 | // in three different directions. This entire class is a frightening, hard-to-maintain | ||
168 | // mess. | ||
169 | if (mChildren.notNull()) | ||
115 | { | 170 | { |
116 | for (LLXMLChildList::iterator iter = mChildren->map.begin(); | 171 | for (LLXMLChildList::iterator iter = mChildren->map.begin(); |
117 | iter != mChildren->map.end(); ++iter) | 172 | iter != mChildren->map.end(); ++iter) |
@@ -124,7 +179,7 @@ LLXMLNode::~LLXMLNode() | |||
124 | mChildren->map.clear(); | 179 | mChildren->map.clear(); |
125 | mChildren->head = NULL; | 180 | mChildren->head = NULL; |
126 | mChildren->tail = NULL; | 181 | mChildren->tail = NULL; |
127 | delete mChildren; | 182 | mChildren = NULL; |
128 | } | 183 | } |
129 | for (LLXMLAttribList::iterator iter = mAttributes.begin(); | 184 | for (LLXMLAttribList::iterator iter = mAttributes.begin(); |
130 | iter != mAttributes.end(); ++iter) | 185 | iter != mAttributes.end(); ++iter) |
@@ -160,7 +215,7 @@ BOOL LLXMLNode::removeChild(LLXMLNode *target_child) | |||
160 | return TRUE; | 215 | return TRUE; |
161 | } | 216 | } |
162 | } | 217 | } |
163 | else if (mChildren) | 218 | else if (mChildren.notNull()) |
164 | { | 219 | { |
165 | LLXMLChildList::iterator children_itr = mChildren->map.find(target_child->mName); | 220 | LLXMLChildList::iterator children_itr = mChildren->map.find(target_child->mName); |
166 | while (children_itr != mChildren->map.end()) | 221 | while (children_itr != mChildren->map.end()) |
@@ -183,7 +238,6 @@ BOOL LLXMLNode::removeChild(LLXMLNode *target_child) | |||
183 | mChildren->map.erase(children_itr); | 238 | mChildren->map.erase(children_itr); |
184 | if (mChildren->map.empty()) | 239 | if (mChildren->map.empty()) |
185 | { | 240 | { |
186 | delete mChildren; | ||
187 | mChildren = NULL; | 241 | mChildren = NULL; |
188 | } | 242 | } |
189 | return TRUE; | 243 | return TRUE; |
@@ -201,7 +255,7 @@ BOOL LLXMLNode::removeChild(LLXMLNode *target_child) | |||
201 | return FALSE; | 255 | return FALSE; |
202 | } | 256 | } |
203 | 257 | ||
204 | void LLXMLNode::addChild(LLXMLNodePtr new_child) | 258 | void LLXMLNode::addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child) |
205 | { | 259 | { |
206 | if (new_child->mParent != NULL) | 260 | if (new_child->mParent != NULL) |
207 | { | 261 | { |
@@ -219,7 +273,7 @@ void LLXMLNode::addChild(LLXMLNodePtr new_child) | |||
219 | } | 273 | } |
220 | else | 274 | else |
221 | { | 275 | { |
222 | if (!mChildren) | 276 | if (mChildren.isNull()) |
223 | { | 277 | { |
224 | mChildren = new LLXMLChildren(); | 278 | mChildren = new LLXMLChildren(); |
225 | mChildren->head = new_child; | 279 | mChildren->head = new_child; |
@@ -227,11 +281,33 @@ void LLXMLNode::addChild(LLXMLNodePtr new_child) | |||
227 | } | 281 | } |
228 | mChildren->map.insert(std::make_pair(new_child->mName, new_child)); | 282 | mChildren->map.insert(std::make_pair(new_child->mName, new_child)); |
229 | 283 | ||
230 | if (mChildren->tail != new_child) | 284 | // if after_child is specified, it damn well better be in the list of children |
285 | // for this node. I'm not going to assert that, because it would be expensive, | ||
286 | // but don't specify that parameter if you didn't get the value for it from the | ||
287 | // list of children of this node! | ||
288 | if (after_child.isNull()) | ||
231 | { | 289 | { |
232 | mChildren->tail->mNext = new_child; | 290 | if (mChildren->tail != new_child) |
233 | new_child->mPrev = mChildren->tail; | 291 | { |
234 | mChildren->tail = new_child; | 292 | mChildren->tail->mNext = new_child; |
293 | new_child->mPrev = mChildren->tail; | ||
294 | mChildren->tail = new_child; | ||
295 | } | ||
296 | } | ||
297 | else | ||
298 | { | ||
299 | if (after_child->mNext.notNull()) | ||
300 | { | ||
301 | // if after_child was not the last item, fix up some pointers | ||
302 | after_child->mNext->mPrev = new_child; | ||
303 | new_child->mNext = after_child->mNext; | ||
304 | } | ||
305 | new_child->mPrev = after_child; | ||
306 | after_child->mNext = new_child; | ||
307 | if (mChildren->tail == after_child) | ||
308 | { | ||
309 | mChildren->tail = new_child; | ||
310 | } | ||
235 | } | 311 | } |
236 | } | 312 | } |
237 | 313 | ||
@@ -293,7 +369,7 @@ void LLXMLNode::updateDefault() | |||
293 | } | 369 | } |
294 | } | 370 | } |
295 | 371 | ||
296 | if (mChildren) | 372 | if (mChildren.notNull()) |
297 | { | 373 | { |
298 | LLXMLChildList::const_iterator children_itr; | 374 | LLXMLChildList::const_iterator children_itr; |
299 | LLXMLChildList::const_iterator children_end = mChildren->map.end(); | 375 | LLXMLChildList::const_iterator children_end = mChildren->map.end(); |
@@ -566,6 +642,24 @@ bool LLXMLNode::updateNode( | |||
566 | } | 642 | } |
567 | 643 | ||
568 | 644 | ||
645 | // static | ||
646 | LLXMLNodePtr LLXMLNode::replaceNode(LLXMLNodePtr node, LLXMLNodePtr update_node) | ||
647 | { | ||
648 | if (!node || !update_node) | ||
649 | { | ||
650 | llwarns << "Node invalid" << llendl; | ||
651 | return node; | ||
652 | } | ||
653 | |||
654 | LLXMLNodePtr cloned_node = update_node->deepCopy(); | ||
655 | node->mParent->addChild(cloned_node, node); // add after node | ||
656 | LLXMLNodePtr parent = node->mParent; | ||
657 | parent->removeChild(node); | ||
658 | parent->updateDefault(); | ||
659 | |||
660 | return cloned_node; | ||
661 | } | ||
662 | |||
569 | 663 | ||
570 | 664 | ||
571 | // static | 665 | // static |
@@ -618,7 +712,7 @@ bool LLXMLNode::parseBuffer( | |||
618 | { | 712 | { |
619 | llwarns << "Error parsing xml error code: " | 713 | llwarns << "Error parsing xml error code: " |
620 | << XML_ErrorString(XML_GetErrorCode(my_parser)) | 714 | << XML_ErrorString(XML_GetErrorCode(my_parser)) |
621 | << " on lne " << XML_GetCurrentLineNumber(my_parser) | 715 | << " on line " << XML_GetCurrentLineNumber(my_parser) |
622 | << llendl; | 716 | << llendl; |
623 | } | 717 | } |
624 | 718 | ||
@@ -722,7 +816,7 @@ BOOL LLXMLNode::isFullyDefault() | |||
722 | && has_default_length | 816 | && has_default_length |
723 | && has_default_attribute) | 817 | && has_default_attribute) |
724 | { | 818 | { |
725 | if (mChildren) | 819 | if (mChildren.notNull()) |
726 | { | 820 | { |
727 | LLXMLChildList::const_iterator children_itr; | 821 | LLXMLChildList::const_iterator children_itr; |
728 | LLXMLChildList::const_iterator children_end = mChildren->map.end(); | 822 | LLXMLChildList::const_iterator children_end = mChildren->map.end(); |
@@ -888,7 +982,7 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i | |||
888 | } | 982 | } |
889 | } | 983 | } |
890 | 984 | ||
891 | if (!mChildren && mValue == "") | 985 | if (mChildren.isNull() && mValue == "") |
892 | { | 986 | { |
893 | output_stream << " />\n"; | 987 | output_stream << " />\n"; |
894 | return; | 988 | return; |
@@ -896,7 +990,7 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i | |||
896 | else | 990 | else |
897 | { | 991 | { |
898 | output_stream << ">\n"; | 992 | output_stream << ">\n"; |
899 | if (mChildren) | 993 | if (mChildren.notNull()) |
900 | { | 994 | { |
901 | // stream non-attributes | 995 | // stream non-attributes |
902 | std::string next_indent = indent + "\t"; | 996 | std::string next_indent = indent + "\t"; |
@@ -922,7 +1016,7 @@ void LLXMLNode::findName(const std::string& name, LLXMLNodeList &results) | |||
922 | results.insert(std::make_pair(this->mName->mString, this)); | 1016 | results.insert(std::make_pair(this->mName->mString, this)); |
923 | return; | 1017 | return; |
924 | } | 1018 | } |
925 | if (mChildren) | 1019 | if (mChildren.notNull()) |
926 | { | 1020 | { |
927 | LLXMLChildList::const_iterator children_itr; | 1021 | LLXMLChildList::const_iterator children_itr; |
928 | LLXMLChildList::const_iterator children_end = mChildren->map.end(); | 1022 | LLXMLChildList::const_iterator children_end = mChildren->map.end(); |
@@ -941,7 +1035,7 @@ void LLXMLNode::findName(LLStringTableEntry* name, LLXMLNodeList &results) | |||
941 | results.insert(std::make_pair(this->mName->mString, this)); | 1035 | results.insert(std::make_pair(this->mName->mString, this)); |
942 | return; | 1036 | return; |
943 | } | 1037 | } |
944 | if (mChildren) | 1038 | if (mChildren.notNull()) |
945 | { | 1039 | { |
946 | LLXMLChildList::const_iterator children_itr; | 1040 | LLXMLChildList::const_iterator children_itr; |
947 | LLXMLChildList::const_iterator children_end = mChildren->map.end(); | 1041 | LLXMLChildList::const_iterator children_end = mChildren->map.end(); |
@@ -960,7 +1054,7 @@ void LLXMLNode::findID(const std::string& id, LLXMLNodeList &results) | |||
960 | results.insert(std::make_pair(this->mName->mString, this)); | 1054 | results.insert(std::make_pair(this->mName->mString, this)); |
961 | return; | 1055 | return; |
962 | } | 1056 | } |
963 | if (mChildren) | 1057 | if (mChildren.notNull()) |
964 | { | 1058 | { |
965 | LLXMLChildList::const_iterator children_itr; | 1059 | LLXMLChildList::const_iterator children_itr; |
966 | LLXMLChildList::const_iterator children_end = mChildren->map.end(); | 1060 | LLXMLChildList::const_iterator children_end = mChildren->map.end(); |
@@ -974,11 +1068,11 @@ void LLXMLNode::findID(const std::string& id, LLXMLNodeList &results) | |||
974 | 1068 | ||
975 | void LLXMLNode::scrubToTree(LLXMLNode *tree) | 1069 | void LLXMLNode::scrubToTree(LLXMLNode *tree) |
976 | { | 1070 | { |
977 | if (!tree || !tree->mChildren) | 1071 | if (!tree || tree->mChildren.isNull()) |
978 | { | 1072 | { |
979 | return; | 1073 | return; |
980 | } | 1074 | } |
981 | if (mChildren) | 1075 | if (mChildren.notNull()) |
982 | { | 1076 | { |
983 | std::vector<LLXMLNodePtr> to_delete_list; | 1077 | std::vector<LLXMLNodePtr> to_delete_list; |
984 | LLXMLChildList::iterator itor = mChildren->map.begin(); | 1078 | LLXMLChildList::iterator itor = mChildren->map.begin(); |
@@ -1023,7 +1117,7 @@ bool LLXMLNode::getChild(const char* name, LLXMLNodePtr& node, BOOL use_default_ | |||
1023 | 1117 | ||
1024 | bool LLXMLNode::getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing) | 1118 | bool LLXMLNode::getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing) |
1025 | { | 1119 | { |
1026 | if (mChildren) | 1120 | if (mChildren.notNull()) |
1027 | { | 1121 | { |
1028 | LLXMLChildList::const_iterator child_itr = mChildren->map.find(name); | 1122 | LLXMLChildList::const_iterator child_itr = mChildren->map.find(name); |
1029 | if (child_itr != mChildren->map.end()) | 1123 | if (child_itr != mChildren->map.end()) |
@@ -1047,7 +1141,7 @@ void LLXMLNode::getChildren(const char* name, LLXMLNodeList &children, BOOL use_ | |||
1047 | 1141 | ||
1048 | void LLXMLNode::getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, BOOL use_default_if_missing) const | 1142 | void LLXMLNode::getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, BOOL use_default_if_missing) const |
1049 | { | 1143 | { |
1050 | if (mChildren) | 1144 | if (mChildren.notNull()) |
1051 | { | 1145 | { |
1052 | LLXMLChildList::const_iterator child_itr = mChildren->map.find(name); | 1146 | LLXMLChildList::const_iterator child_itr = mChildren->map.find(name); |
1053 | if (child_itr != mChildren->map.end()) | 1147 | if (child_itr != mChildren->map.end()) |
@@ -1071,6 +1165,25 @@ void LLXMLNode::getChildren(const LLStringTableEntry* name, LLXMLNodeList &child | |||
1071 | } | 1165 | } |
1072 | } | 1166 | } |
1073 | 1167 | ||
1168 | // recursively walks the tree and returns all children at all nesting levels matching the name | ||
1169 | void LLXMLNode::getDescendants(const LLStringTableEntry* name, LLXMLNodeList &children) const | ||
1170 | { | ||
1171 | if (mChildren.notNull()) | ||
1172 | { | ||
1173 | for (LLXMLChildList::const_iterator child_itr = mChildren->map.begin(); | ||
1174 | child_itr != mChildren->map.end(); ++child_itr) | ||
1175 | { | ||
1176 | LLXMLNodePtr child = (*child_itr).second; | ||
1177 | if (name == child->mName) | ||
1178 | { | ||
1179 | children.insert(std::make_pair(child->mName->mString, child)); | ||
1180 | } | ||
1181 | // and check each child as well | ||
1182 | child->getDescendants(name, children); | ||
1183 | } | ||
1184 | } | ||
1185 | } | ||
1186 | |||
1074 | bool LLXMLNode::getAttribute(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing) | 1187 | bool LLXMLNode::getAttribute(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing) |
1075 | { | 1188 | { |
1076 | return getAttribute(gStringTable.checkStringEntry(name), node, use_default_if_missing); | 1189 | return getAttribute(gStringTable.checkStringEntry(name), node, use_default_if_missing); |
@@ -1111,6 +1224,23 @@ BOOL LLXMLNode::hasAttribute(const char* name ) | |||
1111 | return getAttribute(name, node); | 1224 | return getAttribute(name, node); |
1112 | } | 1225 | } |
1113 | 1226 | ||
1227 | // the structure of these getAttribute_ functions is ugly, but it's because the | ||
1228 | // underlying system is based on BOOL and LLString; if we change | ||
1229 | // so that they're based on more generic mechanisms, these will be | ||
1230 | // simplified. | ||
1231 | bool LLXMLNode::getAttribute_bool(const char* name, bool& value ) | ||
1232 | { | ||
1233 | LLXMLNodePtr node; | ||
1234 | if (!getAttribute(name, node)) | ||
1235 | { | ||
1236 | return false; | ||
1237 | } | ||
1238 | BOOL temp; | ||
1239 | bool retval = node->getBoolValue(1, &temp); | ||
1240 | value = temp; | ||
1241 | return retval; | ||
1242 | } | ||
1243 | |||
1114 | BOOL LLXMLNode::getAttributeBOOL(const char* name, BOOL& value ) | 1244 | BOOL LLXMLNode::getAttributeBOOL(const char* name, BOOL& value ) |
1115 | { | 1245 | { |
1116 | LLXMLNodePtr node; | 1246 | LLXMLNodePtr node; |
@@ -2521,7 +2651,7 @@ void LLXMLNode::setName(LLStringTableEntry* name) | |||
2521 | 2651 | ||
2522 | U32 LLXMLNode::getChildCount() const | 2652 | U32 LLXMLNode::getChildCount() const |
2523 | { | 2653 | { |
2524 | if (mChildren) | 2654 | if (mChildren.notNull()) |
2525 | { | 2655 | { |
2526 | return mChildren->map.size(); | 2656 | return mChildren->map.size(); |
2527 | } | 2657 | } |
@@ -2540,7 +2670,7 @@ U32 get_rand(U32 max_value) | |||
2540 | 2670 | ||
2541 | LLXMLNode *get_rand_node(LLXMLNode *node) | 2671 | LLXMLNode *get_rand_node(LLXMLNode *node) |
2542 | { | 2672 | { |
2543 | if (node->mChildren) | 2673 | if (node->mChildren.notNull()) |
2544 | { | 2674 | { |
2545 | U32 num_children = node->mChildren->map.size(); | 2675 | U32 num_children = node->mChildren->map.size(); |
2546 | if (get_rand(2) == 0) | 2676 | if (get_rand(2) == 0) |
@@ -2748,7 +2878,7 @@ void LLXMLNode::createUnitTest(S32 max_num_children) | |||
2748 | 2878 | ||
2749 | BOOL LLXMLNode::performUnitTest(std::string &error_buffer) | 2879 | BOOL LLXMLNode::performUnitTest(std::string &error_buffer) |
2750 | { | 2880 | { |
2751 | if (!mChildren) | 2881 | if (mChildren.isNull()) |
2752 | { | 2882 | { |
2753 | error_buffer.append(llformat("ERROR Node %s: No children found.\n", mName->mString)); | 2883 | error_buffer.append(llformat("ERROR Node %s: No children found.\n", mName->mString)); |
2754 | return FALSE; | 2884 | return FALSE; |
@@ -3007,14 +3137,14 @@ BOOL LLXMLNode::performUnitTest(std::string &error_buffer) | |||
3007 | return TRUE; | 3137 | return TRUE; |
3008 | } | 3138 | } |
3009 | 3139 | ||
3010 | LLXMLNodePtr LLXMLNode::getFirstChild() | 3140 | LLXMLNodePtr LLXMLNode::getFirstChild() const |
3011 | { | 3141 | { |
3012 | if (!mChildren) return NULL; | 3142 | if (mChildren.isNull()) return NULL; |
3013 | LLXMLNodePtr ret = mChildren->head; | 3143 | LLXMLNodePtr ret = mChildren->head; |
3014 | return ret; | 3144 | return ret; |
3015 | } | 3145 | } |
3016 | 3146 | ||
3017 | LLXMLNodePtr LLXMLNode::getNextSibling() | 3147 | LLXMLNodePtr LLXMLNode::getNextSibling() const |
3018 | { | 3148 | { |
3019 | LLXMLNodePtr ret = mNext; | 3149 | LLXMLNodePtr ret = mNext; |
3020 | return ret; | 3150 | return ret; |
diff --git a/linden/indra/llxml/llxmlnode.h b/linden/indra/llxml/llxmlnode.h index e73b4b1..d4e127b 100644 --- a/linden/indra/llxml/llxmlnode.h +++ b/linden/indra/llxml/llxmlnode.h | |||
@@ -17,7 +17,8 @@ | |||
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | 20 | * online at |
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | 22 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
@@ -87,12 +88,13 @@ class LLVector3d; | |||
87 | class LLVector4; | 88 | class LLVector4; |
88 | class LLVector4U; | 89 | class LLVector4U; |
89 | 90 | ||
90 | struct LLXMLChildren | 91 | struct LLXMLChildren : public LLThreadSafeRefCount |
91 | { | 92 | { |
92 | LLXMLChildList map; // Map of children names->pointers | 93 | LLXMLChildList map; // Map of children names->pointers |
93 | LLXMLNodePtr head; // Head of the double-linked list | 94 | LLXMLNodePtr head; // Head of the double-linked list |
94 | LLXMLNodePtr tail; // Tail of the double-linked list | 95 | LLXMLNodePtr tail; // Tail of the double-linked list |
95 | }; | 96 | }; |
97 | typedef LLPointer<LLXMLChildren> LLXMLChildrenPtr; | ||
96 | 98 | ||
97 | class LLXMLNode : public LLThreadSafeRefCount | 99 | class LLXMLNode : public LLThreadSafeRefCount |
98 | { | 100 | { |
@@ -124,11 +126,13 @@ public: | |||
124 | LLXMLNode(); | 126 | LLXMLNode(); |
125 | LLXMLNode(const char* name, BOOL is_attribute); | 127 | LLXMLNode(const char* name, BOOL is_attribute); |
126 | LLXMLNode(LLStringTableEntry* name, BOOL is_attribute); | 128 | LLXMLNode(LLStringTableEntry* name, BOOL is_attribute); |
129 | LLXMLNode(const LLXMLNode& rhs); | ||
130 | LLXMLNodePtr deepCopy(); | ||
127 | 131 | ||
128 | BOOL isNull(); | 132 | BOOL isNull(); |
129 | 133 | ||
130 | BOOL deleteChild(LLXMLNode* child); | 134 | BOOL deleteChild(LLXMLNode* child); |
131 | void addChild(LLXMLNodePtr new_parent); | 135 | void addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child = LLXMLNodePtr(NULL)); |
132 | void setParent(LLXMLNodePtr new_parent); // reparent if necessary | 136 | void setParent(LLXMLNodePtr new_parent); // reparent if necessary |
133 | 137 | ||
134 | // Serialization | 138 | // Serialization |
@@ -146,8 +150,9 @@ public: | |||
146 | LLXMLNodePtr& node, | 150 | LLXMLNodePtr& node, |
147 | LLXMLNode* defaults); | 151 | LLXMLNode* defaults); |
148 | static bool updateNode( | 152 | static bool updateNode( |
149 | LLXMLNodePtr& node, | 153 | LLXMLNodePtr& node, |
150 | LLXMLNodePtr& update_node); | 154 | LLXMLNodePtr& update_node); |
155 | static LLXMLNodePtr replaceNode(LLXMLNodePtr node, LLXMLNodePtr replacement_node); | ||
151 | static void writeHeaderToFile(LLFILE *fOut); | 156 | static void writeHeaderToFile(LLFILE *fOut); |
152 | void writeToFile(LLFILE *fOut, const std::string& indent = std::string()); | 157 | void writeToFile(LLFILE *fOut, const std::string& indent = std::string()); |
153 | void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string()); | 158 | void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string()); |
@@ -176,6 +181,10 @@ public: | |||
176 | 181 | ||
177 | BOOL hasAttribute(const char* name ); | 182 | BOOL hasAttribute(const char* name ); |
178 | 183 | ||
184 | // these are designed to be more generic versions of the functions | ||
185 | // rather than relying on LL-types | ||
186 | bool getAttribute_bool(const char* name, bool& value ); | ||
187 | |||
179 | BOOL getAttributeBOOL(const char* name, BOOL& value ); | 188 | BOOL getAttributeBOOL(const char* name, BOOL& value ); |
180 | BOOL getAttributeU8(const char* name, U8& value ); | 189 | BOOL getAttributeU8(const char* name, U8& value ); |
181 | BOOL getAttributeS8(const char* name, S8& value ); | 190 | BOOL getAttributeS8(const char* name, S8& value ); |
@@ -211,13 +220,16 @@ public: | |||
211 | bool getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE); | 220 | bool getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE); |
212 | void getChildren(const char* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const; | 221 | void getChildren(const char* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const; |
213 | void getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const; | 222 | void getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const; |
223 | |||
224 | // recursively finds all children at any level matching name | ||
225 | void getDescendants(const LLStringTableEntry* name, LLXMLNodeList &children) const; | ||
214 | 226 | ||
215 | bool getAttribute(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE); | 227 | bool getAttribute(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE); |
216 | bool getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE); | 228 | bool getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE); |
217 | 229 | ||
218 | // The following skip over attributes | 230 | // The following skip over attributes |
219 | LLXMLNodePtr getFirstChild(); | 231 | LLXMLNodePtr getFirstChild() const; |
220 | LLXMLNodePtr getNextSibling(); | 232 | LLXMLNodePtr getNextSibling() const; |
221 | 233 | ||
222 | LLXMLNodePtr getRoot(); | 234 | LLXMLNodePtr getRoot(); |
223 | 235 | ||
@@ -251,7 +263,6 @@ public: | |||
251 | void setName(LLStringTableEntry* name); | 263 | void setName(LLStringTableEntry* name); |
252 | 264 | ||
253 | // Escapes " (quot) ' (apos) & (amp) < (lt) > (gt) | 265 | // Escapes " (quot) ' (apos) & (amp) < (lt) > (gt) |
254 | // TomY TODO: Make this private | ||
255 | static std::string escapeXML(const std::string& xml); | 266 | static std::string escapeXML(const std::string& xml); |
256 | 267 | ||
257 | // Set the default node corresponding to this default node | 268 | // Set the default node corresponding to this default node |
@@ -291,7 +302,7 @@ public: | |||
291 | Encoding mEncoding; // The value encoding | 302 | Encoding mEncoding; // The value encoding |
292 | 303 | ||
293 | LLXMLNode* mParent; // The parent node | 304 | LLXMLNode* mParent; // The parent node |
294 | LLXMLChildren* mChildren; // The child nodes | 305 | LLXMLChildrenPtr mChildren; // The child nodes |
295 | LLXMLAttribList mAttributes; // The attribute nodes | 306 | LLXMLAttribList mAttributes; // The attribute nodes |
296 | LLXMLNodePtr mPrev; // Double-linked list previous node | 307 | LLXMLNodePtr mPrev; // Double-linked list previous node |
297 | LLXMLNodePtr mNext; // Double-linked list next node | 308 | LLXMLNodePtr mNext; // Double-linked list next node |
diff --git a/linden/indra/llxml/llxmlparser.cpp b/linden/indra/llxml/llxmlparser.cpp index 3e87947..7d887f4 100644 --- a/linden/indra/llxml/llxmlparser.cpp +++ b/linden/indra/llxml/llxmlparser.cpp | |||
@@ -17,7 +17,8 @@ | |||
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | 20 | * online at |
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | 22 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llxml/llxmlparser.h b/linden/indra/llxml/llxmlparser.h index 325bf04..d7595f6 100644 --- a/linden/indra/llxml/llxmlparser.h +++ b/linden/indra/llxml/llxmlparser.h | |||
@@ -17,7 +17,8 @@ | |||
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | 20 | * online at |
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | 22 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llxml/llxmltree.cpp b/linden/indra/llxml/llxmltree.cpp index bd1e743..1bce5d2 100644 --- a/linden/indra/llxml/llxmltree.cpp +++ b/linden/indra/llxml/llxmltree.cpp | |||
@@ -17,7 +17,8 @@ | |||
17 | * There are special exceptions to the terms and conditions of the GPL as | 17 | * There are special exceptions to the terms and conditions of the GPL as |
18 | * it is applied to this Source Code. View the full text of the exception | 18 | * it is applied to this Source Code. View the full text of the exception |
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 19 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | 20 | * online at |
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | 22 | * |
22 | * By copying, modifying or distributing this software, you acknowledge | 23 | * By copying, modifying or distributing this software, you acknowledge |
23 | * that you have read and understood your obligations described above, | 24 | * that you have read and understood your obligations described above, |
diff --git a/linden/indra/llxml/llxmltree.h b/linden/indra/llxml/llxmltree.h index 23ec57d..1a020f2 100644 --- a/linden/indra/llxml/llxmltree.h +++ b/linden/indra/llxml/llxmltree.h | |||
@@ -18,7 +18,8 @@ | |||
18 | * There are special exceptions to the terms and conditions of the GPL as | 18 | * There are special exceptions to the terms and conditions of the GPL as |
19 | * it is applied to this Source Code. View the full text of the exception | 19 | * it is applied to this Source Code. View the full text of the exception |
20 | * in the file doc/FLOSS-exception.txt in this software distribution, or | 20 | * in the file doc/FLOSS-exception.txt in this software distribution, or |
21 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | 21 | * online at |
22 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
22 | * | 23 | * |
23 | * By copying, modifying or distributing this software, you acknowledge | 24 | * By copying, modifying or distributing this software, you acknowledge |
24 | * that you have read and understood your obligations described above, | 25 | * that you have read and understood your obligations described above, |