llxmlnode.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /**
  2. * @file llxmlnode.h
  3. * @brief LLXMLNode definition
  4. *
  5. * $LicenseInfo:firstyear=2000&license=viewergpl$
  6. *
  7. * Copyright (c) 2000-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #ifndef LL_LLXMLNODE_H
  33. #define LL_LLXMLNODE_H
  34. #include <map>
  35. #include "expat.h"
  36. #include "indra_constants.h"
  37. #include "llfile.h"
  38. #include "llpointer.h"
  39. #include "llrefcount.h"
  40. #include "llstring.h"
  41. #include "llstringtable.h"
  42. #include "lluuid.h"
  43. class LLColor4;
  44. class LLColor4U;
  45. class LLQuaternion;
  46. class LLVector3;
  47. class LLVector3d;
  48. struct CompareAttributes
  49. {
  50. LL_INLINE bool operator()(const LLStringTableEntry* const lhs,
  51. const LLStringTableEntry* const rhs) const
  52. {
  53. if (lhs == NULL)
  54. {
  55. return true;
  56. }
  57. if (rhs == NULL)
  58. {
  59. return false;
  60. }
  61. return strcmp(lhs->mString, rhs->mString) < 0;
  62. }
  63. };
  64. // Defines a simple node hierarchy for reading and writing task objects
  65. class LLXMLNode;
  66. typedef LLPointer<LLXMLNode> LLXMLNodePtr;
  67. typedef std::multimap<std::string, LLXMLNodePtr > LLXMLNodeList;
  68. typedef std::multimap<const LLStringTableEntry*, LLXMLNodePtr > LLXMLChildList;
  69. typedef std::map<const LLStringTableEntry*, LLXMLNodePtr, CompareAttributes> LLXMLAttribList;
  70. class LLColor4;
  71. class LLColor4U;
  72. class LLSD;
  73. class LLQuaternion;
  74. class LLVector3;
  75. class LLVector3d;
  76. class LLVector4;
  77. class LLVector4U;
  78. struct LLXMLChildren : public LLThreadSafeRefCount
  79. {
  80. LLXMLChildList map; // Map of children names->pointers
  81. LLXMLNodePtr head; // Head of the double-linked list
  82. LLXMLNodePtr tail; // Tail of the double-linked list
  83. };
  84. typedef LLPointer<LLXMLChildren> LLXMLChildrenPtr;
  85. class LLXMLNode : public LLThreadSafeRefCount
  86. {
  87. protected:
  88. LOG_CLASS(LLXMLNode);
  89. public:
  90. enum ValueType
  91. {
  92. TYPE_CONTAINER, // A node which contains nodes
  93. TYPE_UNKNOWN, // A node loaded from file without a specified type
  94. TYPE_BOOLEAN, // "true" or "false"
  95. TYPE_INTEGER, // Any integer type: U8, U32, S32, U64, etc.
  96. TYPE_FLOAT, // Any floating point type: F32, F64
  97. TYPE_STRING, // A string
  98. TYPE_UUID, // An UUID
  99. TYPE_NODEREF, // The ID of another node in the hierarchy to reference
  100. };
  101. enum Encoding
  102. {
  103. ENCODING_DEFAULT = 0,
  104. ENCODING_DECIMAL,
  105. ENCODING_HEX,
  106. // ENCODING_BASE32, // Not implemented yet
  107. };
  108. protected:
  109. ~LLXMLNode();
  110. public:
  111. LLXMLNode();
  112. LLXMLNode(const char* name, bool is_attribute);
  113. LLXMLNode(LLStringTableEntry* name, bool is_attribute);
  114. LLXMLNode(const LLXMLNode& rhs);
  115. LLXMLNodePtr deepCopy();
  116. LL_INLINE bool isNull() { return mName == NULL; }
  117. bool deleteChild(LLXMLNode* child);
  118. void addChild(LLXMLNodePtr new_child,
  119. LLXMLNodePtr after_child = LLXMLNodePtr(NULL));
  120. void setParent(LLXMLNodePtr new_parent); // reparent if necessary
  121. // Deserialization
  122. static bool parseFile(const std::string& filename, LLXMLNodePtr& node,
  123. LLXMLNode* defaults_tree);
  124. static bool parseBuffer(const char* buffer, U64 length, LLXMLNodePtr& node,
  125. LLXMLNode* defaults = NULL);
  126. static bool parseStream(std::istream& str, LLXMLNodePtr& node,
  127. LLXMLNode* defaults = NULL);
  128. static bool updateNode(LLXMLNodePtr& node, LLXMLNodePtr& update_node);
  129. static LLXMLNodePtr replaceNode(LLXMLNodePtr node,
  130. LLXMLNodePtr replacement_node);
  131. static bool getLayeredXMLNode(LLXMLNodePtr& root,
  132. const std::vector<std::string>& paths);
  133. // Write standard XML file header:
  134. // <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
  135. static void writeHeaderToFile(LLFILE* out_file);
  136. // Write XML to file with one attribute per line.
  137. // XML escapes values as they are written.
  138. void writeToFile(LLFILE* out_file,
  139. const std::string& indent = std::string(),
  140. bool use_type_decorations = true);
  141. void writeToOstream(std::ostream& output_stream,
  142. const std::string& indent = std::string(),
  143. bool use_type_decorations = true);
  144. // Utility
  145. void findName(const std::string& name, LLXMLNodeList& results);
  146. void findName(LLStringTableEntry* name, LLXMLNodeList& results);
  147. void findID(const std::string& id, LLXMLNodeList& results);
  148. virtual LLXMLNodePtr createChild(const char* name, bool is_attribute);
  149. virtual LLXMLNodePtr createChild(LLStringTableEntry* name,
  150. bool is_attribute);
  151. // Getters
  152. U32 getBoolValue(U32 expected_length, bool* array);
  153. U32 getByteValue(U32 expected_length, U8* array,
  154. Encoding encoding = ENCODING_DEFAULT);
  155. U32 getIntValue(U32 expected_length, S32* array,
  156. Encoding encoding = ENCODING_DEFAULT);
  157. U32 getUnsignedValue(U32 expected_length, U32* array,
  158. Encoding encoding = ENCODING_DEFAULT);
  159. U32 getLongValue(U32 expected_length, U64* array,
  160. Encoding encoding = ENCODING_DEFAULT);
  161. U32 getFloatValue(U32 expected_length, F32* array,
  162. Encoding encoding = ENCODING_DEFAULT);
  163. U32 getDoubleValue(U32 expected_length, F64* array,
  164. Encoding encoding = ENCODING_DEFAULT);
  165. U32 getStringValue(U32 expected_length, std::string* array);
  166. U32 getUUIDValue(U32 expected_length, LLUUID* array);
  167. U32 getNodeRefValue(U32 expected_length, LLXMLNode** array);
  168. bool hasAttribute(const char* name);
  169. bool getAttributeBool(const char* name, bool& value);
  170. bool getAttributeU8(const char* name, U8& value);
  171. bool getAttributeS8(const char* name, S8& value);
  172. bool getAttributeU16(const char* name, U16& value);
  173. bool getAttributeS16(const char* name, S16& value);
  174. bool getAttributeU32(const char* name, U32& value);
  175. bool getAttributeS32(const char* name, S32& value);
  176. bool getAttributeF32(const char* name, F32& value);
  177. bool getAttributeF64(const char* name, F64& value);
  178. bool getAttributeColor(const char* name, LLColor4& value);
  179. bool getAttributeColor4(const char* name, LLColor4& value);
  180. bool getAttributeColor4U(const char* name, LLColor4U& value);
  181. bool getAttributeVector3(const char* name, LLVector3& value);
  182. bool getAttributeVector3d(const char* name, LLVector3d& value);
  183. bool getAttributeQuat(const char* name, LLQuaternion& value);
  184. bool getAttributeUUID(const char* name, LLUUID& value);
  185. bool getAttributeString(const char* name, std::string& value);
  186. LL_INLINE const ValueType& getType() const { return mType; }
  187. LL_INLINE U32 getLength() const { return mLength; }
  188. LL_INLINE U32 getPrecision() const { return mPrecision; }
  189. LL_INLINE const std::string& getValue() const { return mValue; }
  190. std::string getSanitizedValue() const;
  191. std::string getTextContents() const;
  192. LL_INLINE const LLStringTableEntry* getName() const { return mName; }
  193. LL_INLINE bool hasName(const char* name) const { return mName == gStringTable.checkStringEntry(name); }
  194. LL_INLINE bool hasName(const std::string& name) const { return mName == gStringTable.checkStringEntry(name.c_str()); }
  195. LL_INLINE const std::string& getID() const { return mID; }
  196. LL_INLINE U32 getChildCount() const { return mChildren.notNull() ? (U32)mChildren->map.size() : 0U; }
  197. // getChild returns a Null LLXMLNode (not a NULL pointer) if there is no such child.
  198. // This child has no value so any getTYPEValue() calls on it will return 0.
  199. bool getChild(const char* name, LLXMLNodePtr& node, bool use_default_if_missing = true);
  200. bool getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, bool use_default_if_missing = true);
  201. void getChildren(const char* name, LLXMLNodeList &children, bool use_default_if_missing = true) const;
  202. void getChildren(const LLStringTableEntry* name, LLXMLNodeList& children, bool use_default_if_missing = true) const;
  203. // Recursively finds all children at any level matching name
  204. void getDescendants(const LLStringTableEntry* name, LLXMLNodeList &children) const;
  205. bool getAttribute(const char* name, LLXMLNodePtr& node, bool use_default_if_missing = true);
  206. bool getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, bool use_default_if_missing = true);
  207. LL_INLINE S32 getLineNumber() { return mLineNumber; }
  208. // The following skip over attributes
  209. LLXMLNodePtr getFirstChild() const;
  210. LLXMLNodePtr getNextSibling() const;
  211. LLXMLNodePtr getRoot();
  212. // Setters
  213. bool setAttributeString(const char* attr, const std::string& value);
  214. LL_INLINE void setBoolValue(bool value) { setBoolValue(1, &value); }
  215. LL_INLINE void setByteValue(U8 value, Encoding encoding = ENCODING_DEFAULT)
  216. {
  217. setByteValue(1, &value, encoding);
  218. }
  219. LL_INLINE void setIntValue(S32 value, Encoding encoding = ENCODING_DEFAULT)
  220. {
  221. setIntValue(1, &value, encoding);
  222. }
  223. LL_INLINE void setUnsignedValue(U32 value,
  224. Encoding encoding = ENCODING_DEFAULT)
  225. {
  226. setUnsignedValue(1, &value, encoding);
  227. }
  228. LL_INLINE void setLongValue(U64 value,
  229. Encoding encoding = ENCODING_DEFAULT)
  230. {
  231. setLongValue(1, &value, encoding);
  232. }
  233. LL_INLINE void setFloatValue(F32 value,
  234. Encoding encoding = ENCODING_DEFAULT,
  235. U32 precision = 0)
  236. {
  237. setFloatValue(1, &value, encoding);
  238. }
  239. LL_INLINE void setDoubleValue(F64 value,
  240. Encoding encoding = ENCODING_DEFAULT,
  241. U32 precision = 0)
  242. {
  243. setDoubleValue(1, &value, encoding);
  244. }
  245. LL_INLINE void setStringValue(const std::string& value) { setStringValue(1, &value); }
  246. LL_INLINE void setUUIDValue(const LLUUID value) { setUUIDValue(1, &value); }
  247. LL_INLINE void setNodeRefValue(const LLXMLNode* value) { setNodeRefValue(1, &value); }
  248. void setBoolValue(U32 length, const bool* array);
  249. void setByteValue(U32 length, const U8* array,
  250. Encoding encoding = ENCODING_DEFAULT);
  251. void setIntValue(U32 length, const S32* array,
  252. Encoding encoding = ENCODING_DEFAULT);
  253. void setUnsignedValue(U32 length, const U32* array,
  254. Encoding encoding = ENCODING_DEFAULT);
  255. void setLongValue(U32 length, const U64* array,
  256. Encoding encoding = ENCODING_DEFAULT);
  257. void setFloatValue(U32 length, const F32* array,
  258. Encoding encoding = ENCODING_DEFAULT,
  259. U32 precision = 0);
  260. void setDoubleValue(U32 length, const F64* array,
  261. Encoding encoding = ENCODING_DEFAULT,
  262. U32 precision = 0);
  263. void setStringValue(U32 length, const std::string* array);
  264. void setUUIDValue(U32 length, const LLUUID* array);
  265. void setNodeRefValue(U32 length, const LLXMLNode** array);
  266. void setValue(const std::string& value);
  267. void setName(const std::string& name);
  268. void setName(LLStringTableEntry* name);
  269. LL_INLINE void setLineNumber(S32 line_number) { mLineNumber = line_number; }
  270. // Escapes " (quot) ' (apos) & (amp) < (lt) > (gt)
  271. static std::string escapeXML(const std::string& xml);
  272. // Set the default node corresponding to this default node
  273. LL_INLINE void setDefault(LLXMLNode* default_node) { mDefault = default_node; }
  274. // Find the node within defaults_list which corresponds to this node
  275. void findDefault(LLXMLNode* defaults_listp);
  276. void updateDefault();
  277. // Delete any child nodes that are not among the tree's children, recursive
  278. void scrubToTree(LLXMLNode* treep);
  279. bool deleteChildren(const std::string& name);
  280. bool deleteChildren(LLStringTableEntry* name);
  281. void setAttributes(ValueType type, U32 precision, Encoding encoding,
  282. U32 length);
  283. #if 0 // Unused
  284. LL_INLINE void appendValue(const std::string& value) { mValue.append(value); }
  285. #endif
  286. bool fromXMLRPCValue(LLSD& target);
  287. protected:
  288. bool removeChild(LLXMLNode* child);
  289. bool isFullyDefault();
  290. bool parseXmlRpcArrayValue(LLSD& target);
  291. bool parseXmlRpcStructValue(LLSD& target);
  292. static const char* skipWhitespace(const char* str);
  293. static const char* skipNonWhitespace(const char* str);
  294. static const char* parseInteger(const char* str, U64* dest,
  295. bool* is_negative, U32 precision,
  296. Encoding encoding);
  297. static const char* parseFloat(const char* str, F64* dest, U32 precision,
  298. Encoding encoding);
  299. protected:
  300. LLStringTableEntry* mName; // The name of this node
  301. LLXMLNodePtr mDefault; // Mirror node in the default tree
  302. // The value of this node (use getters/setters only)
  303. // Values are not XML-escaped in memory
  304. // They may contain " (quot) ' (apos) & (amp) < (lt) > (gt)
  305. std::string mValue;
  306. public:
  307. std::string mID; // The ID attribute of this node
  308. // Temporary pointer while loading
  309. XML_Parser* mParser;
  310. LLXMLNode* mParent; // The parent node
  311. LLXMLChildrenPtr mChildren; // The child nodes
  312. LLXMLAttribList mAttributes; // The attribute nodes
  313. LLXMLNodePtr mPrev; // Double-linked list previous node
  314. LLXMLNodePtr mNext; // Double-linked list next node
  315. U32 mVersionMajor; // Version of this tag to use
  316. U32 mVersionMinor;
  317. // If length != 0 then only return arrays of this length
  318. U32 mLength;
  319. U32 mPrecision; // The number of BITS per array item
  320. ValueType mType; // The value type
  321. Encoding mEncoding; // The value encoding
  322. // Line number in source file, if applicable
  323. S32 mLineNumber;
  324. // Flag is only used for output formatting
  325. bool mIsAttribute;
  326. static bool sStripEscapedStrings;
  327. static bool sStripWhitespaceValues;
  328. };
  329. #endif // LL_LLXMLNODE