00001
00032 #ifndef LL_LLXMLNODE_H
00033 #define LL_LLXMLNODE_H
00034
00035 #define XML_STATIC
00036 #ifdef LL_STANDALONE
00037 #include <expat.h>
00038 #else
00039 #include "expat/expat.h"
00040 #endif
00041 #include <map>
00042
00043 #include "indra_constants.h"
00044 #include "llmemory.h"
00045 #include "llthread.h"
00046 #include "llstring.h"
00047 #include "llstringtable.h"
00048
00049
00050
00051 struct CompareAttributes
00052 {
00053 bool operator()(const LLStringTableEntry* const lhs, const LLStringTableEntry* const rhs) const
00054 {
00055 if (lhs == NULL)
00056 return TRUE;
00057 if (rhs == NULL)
00058 return FALSE;
00059
00060 return strcmp(lhs->mString, rhs->mString) < 0;
00061 }
00062 };
00063
00064
00065
00066
00067 class LLXMLNode;
00068 typedef LLPointer<LLXMLNode> LLXMLNodePtr;
00069 typedef std::multimap<LLString, LLXMLNodePtr > LLXMLNodeList;
00070 typedef std::multimap<const LLStringTableEntry *, LLXMLNodePtr > LLXMLChildList;
00071 typedef std::map<const LLStringTableEntry *, LLXMLNodePtr, CompareAttributes> LLXMLAttribList;
00072
00073 struct LLXMLChildren
00074 {
00075 LLXMLChildList map;
00076 LLXMLNodePtr head;
00077 LLXMLNodePtr tail;
00078 };
00079
00080 class LLXMLNode : public LLThreadSafeRefCount
00081 {
00082 public:
00083 enum ValueType
00084 {
00085 TYPE_CONTAINER,
00086 TYPE_UNKNOWN,
00087 TYPE_BOOLEAN,
00088 TYPE_INTEGER,
00089 TYPE_FLOAT,
00090 TYPE_STRING,
00091 TYPE_UUID,
00092 TYPE_NODEREF,
00093 };
00094
00095 enum Encoding
00096 {
00097 ENCODING_DEFAULT = 0,
00098 ENCODING_DECIMAL,
00099 ENCODING_HEX,
00100
00101 };
00102
00103 protected:
00104 ~LLXMLNode();
00105
00106 public:
00107 LLXMLNode();
00108 LLXMLNode(const LLString& name, BOOL is_attribute);
00109 LLXMLNode(LLStringTableEntry* name, BOOL is_attribute);
00110
00111 BOOL isNull();
00112
00113 BOOL deleteChild(LLXMLNode* child);
00114 void addChild(LLXMLNodePtr new_parent);
00115 void setParent(LLXMLNodePtr new_parent);
00116
00117
00118 static bool parseFile(
00119 LLString filename,
00120 LLXMLNodePtr& node,
00121 LLXMLNode* defaults_tree);
00122 static bool parseBuffer(
00123 U8* buffer,
00124 U32 length,
00125 LLXMLNodePtr& node,
00126 LLXMLNode* defaults);
00127 static bool parseStream(
00128 std::istream& str,
00129 LLXMLNodePtr& node,
00130 LLXMLNode* defaults);
00131 static bool updateNode(
00132 LLXMLNodePtr& node,
00133 LLXMLNodePtr& update_node);
00134 static void writeHeaderToFile(FILE *fOut);
00135 void writeToFile(FILE *fOut, LLString indent = LLString());
00136 void writeToOstream(std::ostream& output_stream, const LLString& indent = LLString());
00137
00138
00139 void findName(const LLString& name, LLXMLNodeList &results);
00140 void findName(LLStringTableEntry* name, LLXMLNodeList &results);
00141 void findID(const LLString& id, LLXMLNodeList &results);
00142
00143
00144 virtual LLXMLNodePtr createChild(const LLString& name, BOOL is_attribute);
00145 virtual LLXMLNodePtr createChild(LLStringTableEntry* name, BOOL is_attribute);
00146
00147
00148
00149 U32 getBoolValue(U32 expected_length, BOOL *array);
00150 U32 getByteValue(U32 expected_length, U8 *array, Encoding encoding = ENCODING_DEFAULT);
00151 U32 getIntValue(U32 expected_length, S32 *array, Encoding encoding = ENCODING_DEFAULT);
00152 U32 getUnsignedValue(U32 expected_length, U32 *array, Encoding encoding = ENCODING_DEFAULT);
00153 U32 getLongValue(U32 expected_length, U64 *array, Encoding encoding = ENCODING_DEFAULT);
00154 U32 getFloatValue(U32 expected_length, F32 *array, Encoding encoding = ENCODING_DEFAULT);
00155 U32 getDoubleValue(U32 expected_length, F64 *array, Encoding encoding = ENCODING_DEFAULT);
00156 U32 getStringValue(U32 expected_length, LLString *array);
00157 U32 getUUIDValue(U32 expected_length, LLUUID *array);
00158 U32 getNodeRefValue(U32 expected_length, LLXMLNode **array);
00159
00160 BOOL hasAttribute(const LLString& name );
00161
00162 BOOL getAttributeBOOL(const LLString& name, BOOL& value );
00163 BOOL getAttributeU8(const LLString& name, U8& value );
00164 BOOL getAttributeS8(const LLString& name, S8& value );
00165 BOOL getAttributeU16(const LLString& name, U16& value );
00166 BOOL getAttributeS16(const LLString& name, S16& value );
00167 BOOL getAttributeU32(const LLString& name, U32& value );
00168 BOOL getAttributeS32(const LLString& name, S32& value );
00169 BOOL getAttributeF32(const LLString& name, F32& value );
00170 BOOL getAttributeF64(const LLString& name, F64& value );
00171 BOOL getAttributeColor(const LLString& name, LLColor4& value );
00172 BOOL getAttributeColor4(const LLString& name, LLColor4& value );
00173 BOOL getAttributeColor4U(const LLString& name, LLColor4U& value );
00174 BOOL getAttributeVector3(const LLString& name, LLVector3& value );
00175 BOOL getAttributeVector3d(const LLString& name, LLVector3d& value );
00176 BOOL getAttributeQuat(const LLString& name, LLQuaternion& value );
00177 BOOL getAttributeUUID(const LLString& name, LLUUID& value );
00178 BOOL getAttributeString(const LLString& name, LLString& value );
00179
00180 const ValueType& getType() const { return mType; }
00181 U32 getLength() const { return mLength; }
00182 U32 getPrecision() const { return mPrecision; }
00183 const LLString& getValue() const { return mValue; }
00184 LLString getTextContents() const;
00185 const LLStringTableEntry* getName() const { return mName; }
00186 BOOL hasName(const char* name) const { return mName == gStringTable.checkStringEntry(name); }
00187 BOOL hasName(LLString name) const { return mName == gStringTable.checkStringEntry(name.c_str()); }
00188 const LLString& getID() const { return mID; }
00189
00190 U32 getChildCount() const;
00191
00192
00193 bool getChild(const LLString& name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
00194 bool getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
00195 void getChildren(const LLString& name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const;
00196 void getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const;
00197
00198 bool getAttribute(const LLString& name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
00199 bool getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
00200
00201
00202 LLXMLNodePtr getFirstChild();
00203 LLXMLNodePtr getNextSibling();
00204
00205 LLXMLNodePtr getRoot();
00206
00207
00208
00209 bool setAttributeString(const LLString& attr, const LLString& value);
00210
00211 void setBoolValue(const BOOL value) { setBoolValue(1, &value); }
00212 void setByteValue(const U8 value, Encoding encoding = ENCODING_DEFAULT) { setByteValue(1, &value, encoding); }
00213 void setIntValue(const S32 value, Encoding encoding = ENCODING_DEFAULT) { setIntValue(1, &value, encoding); }
00214 void setUnsignedValue(const U32 value, Encoding encoding = ENCODING_DEFAULT) { setUnsignedValue(1, &value, encoding); }
00215 void setLongValue(const U64 value, Encoding encoding = ENCODING_DEFAULT) { setLongValue(1, &value, encoding); }
00216 void setFloatValue(const F32 value, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0) { setFloatValue(1, &value, encoding); }
00217 void setDoubleValue(const F64 value, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0) { setDoubleValue(1, &value, encoding); }
00218 void setStringValue(const LLString value) { setStringValue(1, &value); }
00219 void setUUIDValue(const LLUUID value) { setUUIDValue(1, &value); }
00220 void setNodeRefValue(const LLXMLNode *value) { setNodeRefValue(1, &value); }
00221
00222 void setBoolValue(U32 length, const BOOL *array);
00223 void setByteValue(U32 length, const U8 *array, Encoding encoding = ENCODING_DEFAULT);
00224 void setIntValue(U32 length, const S32 *array, Encoding encoding = ENCODING_DEFAULT);
00225 void setUnsignedValue(U32 length, const U32* array, Encoding encoding = ENCODING_DEFAULT);
00226 void setLongValue(U32 length, const U64 *array, Encoding encoding = ENCODING_DEFAULT);
00227 void setFloatValue(U32 length, const F32 *array, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0);
00228 void setDoubleValue(U32 length, const F64 *array, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0);
00229 void setStringValue(U32 length, const LLString *array);
00230 void setUUIDValue(U32 length, const LLUUID *array);
00231 void setNodeRefValue(U32 length, const LLXMLNode **array);
00232 void setValue(const LLString& value);
00233 void setName(const LLString& name);
00234 void setName(LLStringTableEntry* name);
00235
00236
00237
00238 static LLString escapeXML(const LLString& xml);
00239
00240
00241 void setDefault(LLXMLNode *default_node);
00242
00243
00244 void findDefault(LLXMLNode *defaults_list);
00245
00246 void updateDefault();
00247
00248
00249 void scrubToTree(LLXMLNode *tree);
00250
00251 BOOL deleteChildren(const LLString& name);
00252 BOOL deleteChildren(LLStringTableEntry* name);
00253 void setAttributes(ValueType type, U32 precision, Encoding encoding, U32 length);
00254 void appendValue(const LLString& value);
00255
00256
00257 void createUnitTest(S32 max_num_children);
00258 BOOL performUnitTest(LLString &error_buffer);
00259
00260 protected:
00261 BOOL removeChild(LLXMLNode* child);
00262
00263 public:
00264 LLString mID;
00265
00266 XML_Parser *mParser;
00267
00268 BOOL mIsAttribute;
00269 U32 mVersionMajor;
00270 U32 mVersionMinor;
00271 U32 mLength;
00272 U32 mPrecision;
00273 ValueType mType;
00274 Encoding mEncoding;
00275
00276 LLXMLNode* mParent;
00277 LLXMLChildren* mChildren;
00278 LLXMLAttribList mAttributes;
00279 LLXMLNodePtr mPrev;
00280 LLXMLNodePtr mNext;
00281
00282 static BOOL sStripEscapedStrings;
00283 static BOOL sStripWhitespaceValues;
00284
00285 protected:
00286 LLStringTableEntry *mName;
00287 LLString mValue;
00288
00289 LLXMLNodePtr mDefault;
00290
00291 static const char *skipWhitespace(const char *str);
00292 static const char *skipNonWhitespace(const char *str);
00293 static const char *parseInteger(const char *str, U64 *dest, BOOL *is_negative, U32 precision, Encoding encoding);
00294 static const char *parseFloat(const char *str, F64 *dest, U32 precision, Encoding encoding);
00295
00296 BOOL isFullyDefault();
00297 };
00298
00299 #endif // LL_LLXMLNODE