llxmlnode.h

Go to the documentation of this file.
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 // Defines a simple node hierarchy for reading and writing task objects
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;                     // Map of children names->pointers
00078         LLXMLNodePtr head;                      // Head of the double-linked list
00079         LLXMLNodePtr tail;                      // Tail of the double-linked list
00080 };
00081 
00082 class LLXMLNode : public LLThreadSafeRefCount
00083 {
00084 public:
00085         enum ValueType
00086         {
00087                 TYPE_CONTAINER,         // A node which contains nodes
00088                 TYPE_UNKNOWN,           // A node loaded from file without a specified type
00089                 TYPE_BOOLEAN,           // "true" or "false"
00090                 TYPE_INTEGER,           // any integer type: U8, U32, S32, U64, etc.
00091                 TYPE_FLOAT,                     // any floating point type: F32, F64
00092                 TYPE_STRING,            // a string
00093                 TYPE_UUID,                      // a UUID
00094                 TYPE_NODEREF,           // the ID of another node in the hierarchy to reference
00095         };
00096 
00097         enum Encoding
00098         {
00099                 ENCODING_DEFAULT = 0,
00100                 ENCODING_DECIMAL,
00101                 ENCODING_HEX,
00102                 // ENCODING_BASE32, // Not implemented yet
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); // reparent if necessary
00118 
00119     // Serialization
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     // Utility
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     // Getters
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     // getChild returns a Null LLXMLNode (not a NULL pointer) if there is no such child.
00194     // This child has no value so any getTYPEValue() calls on it will return 0.
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         // The following skip over attributes
00204         LLXMLNodePtr getFirstChild();
00205         LLXMLNodePtr getNextSibling();
00206 
00207     LLXMLNodePtr getRoot();
00208 
00209         // Setters
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         // Escapes " (quot) ' (apos) & (amp) < (lt) > (gt)
00239         // TomY TODO: Make this private
00240         static LLString escapeXML(const LLString& xml);
00241 
00242         // Set the default node corresponding to this default node
00243         void setDefault(LLXMLNode *default_node);
00244 
00245         // Find the node within defaults_list which corresponds to this node
00246         void findDefault(LLXMLNode *defaults_list);
00247 
00248         void updateDefault();
00249 
00250         // Delete any child nodes that aren't among the tree's children, recursive
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         // Unit Testing
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;                           // The ID attribute of this node
00267 
00268         XML_Parser *mParser;            // Temporary pointer while loading
00269 
00270         BOOL mIsAttribute;                      // Flag is only used for output formatting
00271         U32 mVersionMajor;                      // Version of this tag to use
00272         U32 mVersionMinor;
00273         U32 mLength;                            // If the length is nonzero, then only return arrays of this length
00274         U32 mPrecision;                         // The number of BITS per array item
00275         ValueType mType;                        // The value type
00276         Encoding mEncoding;                     // The value encoding
00277 
00278         LLXMLNode* mParent;                             // The parent node
00279         LLXMLChildren* mChildren;               // The child nodes
00280         LLXMLAttribList mAttributes;            // The attribute nodes
00281         LLXMLNodePtr mPrev;                             // Double-linked list previous node
00282         LLXMLNodePtr mNext;                             // Double-linked list next node
00283 
00284         static BOOL sStripEscapedStrings;
00285         static BOOL sStripWhitespaceValues;
00286         
00287 protected:
00288         LLStringTableEntry *mName;              // The name of this node
00289         LLString mValue;                        // The value of this node (use getters/setters only)
00290 
00291         LLXMLNodePtr mDefault;          // Mirror node in the default tree
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

Generated on Fri May 16 08:33:06 2008 for SecondLife by  doxygen 1.5.5