llxmlnode.h

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

Generated on Thu Jul 1 06:09:48 2010 for Second Life Viewer by  doxygen 1.4.7