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