PageRenderTime 53ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llxml/llxmlnode.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 341 lines | 228 code | 63 blank | 50 comment | 6 complexity | de835d93aba0bec26021dca1e8b52ddd MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llxmlnode.h
  3. * @brief LLXMLNode definition
  4. *
  5. * $LicenseInfo:firstyear=2000&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #ifndef LL_LLXMLNODE_H
  27. #define LL_LLXMLNODE_H
  28. #ifndef XML_STATIC
  29. #define XML_STATIC
  30. #endif
  31. #ifdef LL_STANDALONE
  32. #include <expat.h>
  33. #else
  34. #include "expat/expat.h"
  35. #endif
  36. #include <map>
  37. #include "indra_constants.h"
  38. #include "llpointer.h"
  39. #include "llthread.h" // LLThreadSafeRefCount
  40. #include "llstring.h"
  41. #include "llstringtable.h"
  42. #include "llfile.h"
  43. class LLVector3;
  44. class LLVector3d;
  45. class LLQuaternion;
  46. class LLUUID;
  47. class LLColor4;
  48. class LLColor4U;
  49. struct CompareAttributes
  50. {
  51. bool operator()(const LLStringTableEntry* const lhs, const LLStringTableEntry* const rhs) const
  52. {
  53. if (lhs == NULL)
  54. return TRUE;
  55. if (rhs == NULL)
  56. return FALSE;
  57. return strcmp(lhs->mString, rhs->mString) < 0;
  58. }
  59. };
  60. // Defines a simple node hierarchy for reading and writing task objects
  61. class LLXMLNode;
  62. typedef LLPointer<LLXMLNode> LLXMLNodePtr;
  63. typedef std::multimap<std::string, LLXMLNodePtr > LLXMLNodeList;
  64. typedef std::multimap<const LLStringTableEntry *, LLXMLNodePtr > LLXMLChildList;
  65. typedef std::map<const LLStringTableEntry *, LLXMLNodePtr, CompareAttributes> LLXMLAttribList;
  66. class LLColor4;
  67. class LLColor4U;
  68. class LLQuaternion;
  69. class LLVector3;
  70. class LLVector3d;
  71. class LLVector4;
  72. class LLVector4U;
  73. struct LLXMLChildren : public LLThreadSafeRefCount
  74. {
  75. LLXMLChildList map; // Map of children names->pointers
  76. LLXMLNodePtr head; // Head of the double-linked list
  77. LLXMLNodePtr tail; // Tail of the double-linked list
  78. };
  79. typedef LLPointer<LLXMLChildren> LLXMLChildrenPtr;
  80. class LLXMLNode : public LLThreadSafeRefCount
  81. {
  82. public:
  83. enum ValueType
  84. {
  85. TYPE_CONTAINER, // A node which contains nodes
  86. TYPE_UNKNOWN, // A node loaded from file without a specified type
  87. TYPE_BOOLEAN, // "true" or "false"
  88. TYPE_INTEGER, // any integer type: U8, U32, S32, U64, etc.
  89. TYPE_FLOAT, // any floating point type: F32, F64
  90. TYPE_STRING, // a string
  91. TYPE_UUID, // a UUID
  92. TYPE_NODEREF, // the ID of another node in the hierarchy to reference
  93. };
  94. enum Encoding
  95. {
  96. ENCODING_DEFAULT = 0,
  97. ENCODING_DECIMAL,
  98. ENCODING_HEX,
  99. // ENCODING_BASE32, // Not implemented yet
  100. };
  101. protected:
  102. ~LLXMLNode();
  103. public:
  104. LLXMLNode();
  105. LLXMLNode(const char* name, BOOL is_attribute);
  106. LLXMLNode(LLStringTableEntry* name, BOOL is_attribute);
  107. LLXMLNode(const LLXMLNode& rhs);
  108. LLXMLNodePtr deepCopy();
  109. BOOL isNull();
  110. BOOL deleteChild(LLXMLNode* child);
  111. void addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child = LLXMLNodePtr(NULL));
  112. void setParent(LLXMLNodePtr new_parent); // reparent if necessary
  113. // Serialization
  114. static bool parseFile(
  115. const std::string& filename,
  116. LLXMLNodePtr& node,
  117. LLXMLNode* defaults_tree);
  118. static bool parseBuffer(
  119. U8* buffer,
  120. U32 length,
  121. LLXMLNodePtr& node,
  122. LLXMLNode* defaults);
  123. static bool parseStream(
  124. std::istream& str,
  125. LLXMLNodePtr& node,
  126. LLXMLNode* defaults);
  127. static bool updateNode(
  128. LLXMLNodePtr& node,
  129. LLXMLNodePtr& update_node);
  130. static LLXMLNodePtr replaceNode(LLXMLNodePtr node, LLXMLNodePtr replacement_node);
  131. static bool getLayeredXMLNode(LLXMLNodePtr& root, const std::vector<std::string>& paths);
  132. // Write standard XML file header:
  133. // <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
  134. static void writeHeaderToFile(LLFILE *out_file);
  135. // Write XML to file with one attribute per line.
  136. // XML escapes values as they are written.
  137. void writeToFile(LLFILE *out_file, const std::string& indent = std::string(), bool use_type_decorations=true);
  138. void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string(), bool use_type_decorations=true);
  139. // Utility
  140. void findName(const std::string& name, LLXMLNodeList &results);
  141. void findName(LLStringTableEntry* name, LLXMLNodeList &results);
  142. void findID(const std::string& id, LLXMLNodeList &results);
  143. virtual LLXMLNodePtr createChild(const char* name, BOOL is_attribute);
  144. virtual LLXMLNodePtr createChild(LLStringTableEntry* name, BOOL is_attribute);
  145. // Getters
  146. U32 getBoolValue(U32 expected_length, BOOL *array);
  147. U32 getByteValue(U32 expected_length, U8 *array, Encoding encoding = ENCODING_DEFAULT);
  148. U32 getIntValue(U32 expected_length, S32 *array, Encoding encoding = ENCODING_DEFAULT);
  149. U32 getUnsignedValue(U32 expected_length, U32 *array, Encoding encoding = ENCODING_DEFAULT);
  150. U32 getLongValue(U32 expected_length, U64 *array, Encoding encoding = ENCODING_DEFAULT);
  151. U32 getFloatValue(U32 expected_length, F32 *array, Encoding encoding = ENCODING_DEFAULT);
  152. U32 getDoubleValue(U32 expected_length, F64 *array, Encoding encoding = ENCODING_DEFAULT);
  153. U32 getStringValue(U32 expected_length, std::string *array);
  154. U32 getUUIDValue(U32 expected_length, LLUUID *array);
  155. U32 getNodeRefValue(U32 expected_length, LLXMLNode **array);
  156. BOOL hasAttribute(const char* name );
  157. // these are designed to be more generic versions of the functions
  158. // rather than relying on LL-types
  159. bool getAttribute_bool(const char* name, bool& value );
  160. BOOL getAttributeBOOL(const char* name, BOOL& value );
  161. BOOL getAttributeU8(const char* name, U8& value );
  162. BOOL getAttributeS8(const char* name, S8& value );
  163. BOOL getAttributeU16(const char* name, U16& value );
  164. BOOL getAttributeS16(const char* name, S16& value );
  165. BOOL getAttributeU32(const char* name, U32& value );
  166. BOOL getAttributeS32(const char* name, S32& value );
  167. BOOL getAttributeF32(const char* name, F32& value );
  168. BOOL getAttributeF64(const char* name, F64& value );
  169. BOOL getAttributeColor(const char* name, LLColor4& value );
  170. BOOL getAttributeColor4(const char* name, LLColor4& value );
  171. BOOL getAttributeColor4U(const char* name, LLColor4U& value );
  172. BOOL getAttributeVector3(const char* name, LLVector3& value );
  173. BOOL getAttributeVector3d(const char* name, LLVector3d& value );
  174. BOOL getAttributeQuat(const char* name, LLQuaternion& value );
  175. BOOL getAttributeUUID(const char* name, LLUUID& value );
  176. BOOL getAttributeString(const char* name, std::string& value );
  177. const ValueType& getType() const { return mType; }
  178. U32 getLength() const { return mLength; }
  179. U32 getPrecision() const { return mPrecision; }
  180. const std::string& getValue() const { return mValue; }
  181. std::string getSanitizedValue() const;
  182. std::string getTextContents() const;
  183. const LLStringTableEntry* getName() const { return mName; }
  184. BOOL hasName(const char* name) const { return mName == gStringTable.checkStringEntry(name); }
  185. BOOL hasName(const std::string& name) const { return mName == gStringTable.checkStringEntry(name.c_str()); }
  186. const std::string& getID() const { return mID; }
  187. U32 getChildCount() const;
  188. // getChild returns a Null LLXMLNode (not a NULL pointer) if there is no such child.
  189. // This child has no value so any getTYPEValue() calls on it will return 0.
  190. bool getChild(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
  191. bool getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
  192. void getChildren(const char* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const;
  193. void getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const;
  194. // recursively finds all children at any level matching name
  195. void getDescendants(const LLStringTableEntry* name, LLXMLNodeList &children) const;
  196. bool getAttribute(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
  197. bool getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
  198. S32 getLineNumber();
  199. // The following skip over attributes
  200. LLXMLNodePtr getFirstChild() const;
  201. LLXMLNodePtr getNextSibling() const;
  202. LLXMLNodePtr getRoot();
  203. // Setters
  204. bool setAttributeString(const char* attr, const std::string& value);
  205. void setBoolValue(const BOOL value) { setBoolValue(1, &value); }
  206. void setByteValue(const U8 value, Encoding encoding = ENCODING_DEFAULT) { setByteValue(1, &value, encoding); }
  207. void setIntValue(const S32 value, Encoding encoding = ENCODING_DEFAULT) { setIntValue(1, &value, encoding); }
  208. void setUnsignedValue(const U32 value, Encoding encoding = ENCODING_DEFAULT) { setUnsignedValue(1, &value, encoding); }
  209. void setLongValue(const U64 value, Encoding encoding = ENCODING_DEFAULT) { setLongValue(1, &value, encoding); }
  210. void setFloatValue(const F32 value, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0) { setFloatValue(1, &value, encoding); }
  211. void setDoubleValue(const F64 value, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0) { setDoubleValue(1, &value, encoding); }
  212. void setStringValue(const std::string& value) { setStringValue(1, &value); }
  213. void setUUIDValue(const LLUUID value) { setUUIDValue(1, &value); }
  214. void setNodeRefValue(const LLXMLNode *value) { setNodeRefValue(1, &value); }
  215. void setBoolValue(U32 length, const BOOL *array);
  216. void setByteValue(U32 length, const U8 *array, Encoding encoding = ENCODING_DEFAULT);
  217. void setIntValue(U32 length, const S32 *array, Encoding encoding = ENCODING_DEFAULT);
  218. void setUnsignedValue(U32 length, const U32* array, Encoding encoding = ENCODING_DEFAULT);
  219. void setLongValue(U32 length, const U64 *array, Encoding encoding = ENCODING_DEFAULT);
  220. void setFloatValue(U32 length, const F32 *array, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0);
  221. void setDoubleValue(U32 length, const F64 *array, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0);
  222. void setStringValue(U32 length, const std::string *array);
  223. void setUUIDValue(U32 length, const LLUUID *array);
  224. void setNodeRefValue(U32 length, const LLXMLNode **array);
  225. void setValue(const std::string& value);
  226. void setName(const std::string& name);
  227. void setName(LLStringTableEntry* name);
  228. void setLineNumber(S32 line_number);
  229. // Escapes " (quot) ' (apos) & (amp) < (lt) > (gt)
  230. static std::string escapeXML(const std::string& xml);
  231. // Set the default node corresponding to this default node
  232. void setDefault(LLXMLNode *default_node);
  233. // Find the node within defaults_list which corresponds to this node
  234. void findDefault(LLXMLNode *defaults_list);
  235. void updateDefault();
  236. // Delete any child nodes that aren't among the tree's children, recursive
  237. void scrubToTree(LLXMLNode *tree);
  238. BOOL deleteChildren(const std::string& name);
  239. BOOL deleteChildren(LLStringTableEntry* name);
  240. void setAttributes(ValueType type, U32 precision, Encoding encoding, U32 length);
  241. // void appendValue(const std::string& value); // Unused
  242. // Unit Testing
  243. void createUnitTest(S32 max_num_children);
  244. BOOL performUnitTest(std::string &error_buffer);
  245. protected:
  246. BOOL removeChild(LLXMLNode* child);
  247. public:
  248. std::string mID; // The ID attribute of this node
  249. XML_Parser *mParser; // Temporary pointer while loading
  250. BOOL mIsAttribute; // Flag is only used for output formatting
  251. U32 mVersionMajor; // Version of this tag to use
  252. U32 mVersionMinor;
  253. U32 mLength; // If the length is nonzero, then only return arrays of this length
  254. U32 mPrecision; // The number of BITS per array item
  255. ValueType mType; // The value type
  256. Encoding mEncoding; // The value encoding
  257. S32 mLineNumber; // line number in source file, if applicable
  258. LLXMLNode* mParent; // The parent node
  259. LLXMLChildrenPtr mChildren; // The child nodes
  260. LLXMLAttribList mAttributes; // The attribute nodes
  261. LLXMLNodePtr mPrev; // Double-linked list previous node
  262. LLXMLNodePtr mNext; // Double-linked list next node
  263. static BOOL sStripEscapedStrings;
  264. static BOOL sStripWhitespaceValues;
  265. protected:
  266. LLStringTableEntry *mName; // The name of this node
  267. // The value of this node (use getters/setters only)
  268. // Values are not XML-escaped in memory
  269. // They may contain " (quot) ' (apos) & (amp) < (lt) > (gt)
  270. std::string mValue;
  271. LLXMLNodePtr mDefault; // Mirror node in the default tree
  272. static const char *skipWhitespace(const char *str);
  273. static const char *skipNonWhitespace(const char *str);
  274. static const char *parseInteger(const char *str, U64 *dest, BOOL *is_negative, U32 precision, Encoding encoding);
  275. static const char *parseFloat(const char *str, F64 *dest, U32 precision, Encoding encoding);
  276. BOOL isFullyDefault();
  277. };
  278. #endif // LL_LLXMLNODE