PageRenderTime 49ms CodeModel.GetById 11ms app.highlight 32ms RepoModel.GetById 1ms 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
  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
 27#ifndef LL_LLXMLNODE_H
 28#define LL_LLXMLNODE_H
 29
 30#ifndef XML_STATIC
 31#define XML_STATIC
 32#endif
 33#ifdef LL_STANDALONE
 34#include <expat.h>
 35#else
 36#include "expat/expat.h"
 37#endif
 38#include <map>
 39
 40#include "indra_constants.h"
 41#include "llpointer.h"
 42#include "llthread.h"		// LLThreadSafeRefCount
 43#include "llstring.h"
 44#include "llstringtable.h"
 45#include "llfile.h"
 46
 47
 48class LLVector3;
 49class LLVector3d;
 50class LLQuaternion;
 51class LLUUID;
 52class LLColor4;
 53class LLColor4U;
 54
 55
 56struct CompareAttributes
 57{
 58	bool operator()(const LLStringTableEntry* const lhs, const LLStringTableEntry* const rhs) const
 59	{	
 60		if (lhs == NULL)
 61			return TRUE;
 62		if (rhs == NULL)
 63			return FALSE;
 64
 65		return strcmp(lhs->mString, rhs->mString) < 0;
 66	}
 67};
 68
 69
 70// Defines a simple node hierarchy for reading and writing task objects
 71
 72class LLXMLNode;
 73typedef LLPointer<LLXMLNode> LLXMLNodePtr;
 74typedef std::multimap<std::string, LLXMLNodePtr > LLXMLNodeList;
 75typedef std::multimap<const LLStringTableEntry *, LLXMLNodePtr > LLXMLChildList;
 76typedef std::map<const LLStringTableEntry *, LLXMLNodePtr, CompareAttributes> LLXMLAttribList;
 77
 78class LLColor4;
 79class LLColor4U;
 80class LLQuaternion;
 81class LLVector3;
 82class LLVector3d;
 83class LLVector4;
 84class LLVector4U;
 85
 86struct LLXMLChildren : public LLThreadSafeRefCount
 87{
 88	LLXMLChildList map;			// Map of children names->pointers
 89	LLXMLNodePtr head;			// Head of the double-linked list
 90	LLXMLNodePtr tail;			// Tail of the double-linked list
 91};
 92typedef LLPointer<LLXMLChildren> LLXMLChildrenPtr;
 93
 94class LLXMLNode : public LLThreadSafeRefCount
 95{
 96public:
 97	enum ValueType
 98	{
 99		TYPE_CONTAINER,		// A node which contains nodes
100		TYPE_UNKNOWN,		// A node loaded from file without a specified type
101		TYPE_BOOLEAN,		// "true" or "false"
102		TYPE_INTEGER,		// any integer type: U8, U32, S32, U64, etc.
103		TYPE_FLOAT,			// any floating point type: F32, F64
104		TYPE_STRING,		// a string
105		TYPE_UUID,			// a UUID
106		TYPE_NODEREF,		// the ID of another node in the hierarchy to reference
107	};
108
109	enum Encoding
110	{
111		ENCODING_DEFAULT = 0,
112		ENCODING_DECIMAL,
113		ENCODING_HEX,
114		// ENCODING_BASE32, // Not implemented yet
115	};
116
117protected:
118	~LLXMLNode();
119
120public:
121	LLXMLNode();
122	LLXMLNode(const char* name, BOOL is_attribute);
123	LLXMLNode(LLStringTableEntry* name, BOOL is_attribute);
124	LLXMLNode(const LLXMLNode& rhs);
125	LLXMLNodePtr deepCopy();
126
127	BOOL isNull();
128
129	BOOL deleteChild(LLXMLNode* child);
130    void addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child = LLXMLNodePtr(NULL)); 
131    void setParent(LLXMLNodePtr new_parent); // reparent if necessary
132
133    // Serialization
134	static bool parseFile(
135		const std::string& filename,
136		LLXMLNodePtr& node, 
137		LLXMLNode* defaults_tree);
138	static bool parseBuffer(
139		U8* buffer,
140		U32 length,
141		LLXMLNodePtr& node, 
142		LLXMLNode* defaults);
143	static bool parseStream(
144		std::istream& str,
145		LLXMLNodePtr& node, 
146		LLXMLNode* defaults);
147	static bool updateNode(
148		LLXMLNodePtr& node,
149		LLXMLNodePtr& update_node);
150	static LLXMLNodePtr replaceNode(LLXMLNodePtr node, LLXMLNodePtr replacement_node);
151	
152	static bool getLayeredXMLNode(LLXMLNodePtr& root, const std::vector<std::string>& paths);
153	
154	
155	// Write standard XML file header:
156	// <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
157	static void writeHeaderToFile(LLFILE *out_file);
158	
159	// Write XML to file with one attribute per line.
160	// XML escapes values as they are written.
161    void writeToFile(LLFILE *out_file, const std::string& indent = std::string(), bool use_type_decorations=true);
162    void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string(), bool use_type_decorations=true);
163
164    // Utility
165    void findName(const std::string& name, LLXMLNodeList &results);
166    void findName(LLStringTableEntry* name, LLXMLNodeList &results);
167    void findID(const std::string& id, LLXMLNodeList &results);
168
169
170    virtual LLXMLNodePtr createChild(const char* name, BOOL is_attribute);
171    virtual LLXMLNodePtr createChild(LLStringTableEntry* name, BOOL is_attribute);
172
173
174    // Getters
175    U32 getBoolValue(U32 expected_length, BOOL *array);
176    U32 getByteValue(U32 expected_length, U8 *array, Encoding encoding = ENCODING_DEFAULT);
177    U32 getIntValue(U32 expected_length, S32 *array, Encoding encoding = ENCODING_DEFAULT);
178    U32 getUnsignedValue(U32 expected_length, U32 *array, Encoding encoding = ENCODING_DEFAULT);
179    U32 getLongValue(U32 expected_length, U64 *array, Encoding encoding = ENCODING_DEFAULT);
180    U32 getFloatValue(U32 expected_length, F32 *array, Encoding encoding = ENCODING_DEFAULT);
181    U32 getDoubleValue(U32 expected_length, F64 *array, Encoding encoding = ENCODING_DEFAULT);
182    U32 getStringValue(U32 expected_length, std::string *array);
183    U32 getUUIDValue(U32 expected_length, LLUUID *array);
184    U32 getNodeRefValue(U32 expected_length, LLXMLNode **array);
185
186	BOOL hasAttribute(const char* name );
187
188        // these are designed to be more generic versions of the functions
189    // rather than relying on LL-types
190    bool getAttribute_bool(const char* name, bool& value ); 
191
192	BOOL getAttributeBOOL(const char* name, BOOL& value );
193	BOOL getAttributeU8(const char* name, U8& value );
194	BOOL getAttributeS8(const char* name, S8& value );
195	BOOL getAttributeU16(const char* name, U16& value );
196	BOOL getAttributeS16(const char* name, S16& value );
197	BOOL getAttributeU32(const char* name, U32& value );
198	BOOL getAttributeS32(const char* name, S32& value );
199	BOOL getAttributeF32(const char* name, F32& value );
200	BOOL getAttributeF64(const char* name, F64& value );
201	BOOL getAttributeColor(const char* name, LLColor4& value );
202	BOOL getAttributeColor4(const char* name, LLColor4& value );
203	BOOL getAttributeColor4U(const char* name, LLColor4U& value );
204	BOOL getAttributeVector3(const char* name, LLVector3& value );
205	BOOL getAttributeVector3d(const char* name, LLVector3d& value );
206	BOOL getAttributeQuat(const char* name, LLQuaternion& value );
207	BOOL getAttributeUUID(const char* name, LLUUID& value );
208	BOOL getAttributeString(const char* name, std::string& value );
209
210    const ValueType& getType() const { return mType; }
211    U32 getLength() const { return mLength; }
212    U32 getPrecision() const { return mPrecision; }
213    const std::string& getValue() const { return mValue; }
214	std::string getSanitizedValue() const;
215	std::string getTextContents() const;
216    const LLStringTableEntry* getName() const { return mName; }
217	BOOL hasName(const char* name) const { return mName == gStringTable.checkStringEntry(name); }
218	BOOL hasName(const std::string& name) const { return mName == gStringTable.checkStringEntry(name.c_str()); }
219    const std::string& getID() const { return mID; }
220
221    U32 getChildCount() const;
222    // getChild returns a Null LLXMLNode (not a NULL pointer) if there is no such child.
223    // This child has no value so any getTYPEValue() calls on it will return 0.
224    bool getChild(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
225    bool getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
226    void getChildren(const char* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const;
227    void getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const;
228	
229	// recursively finds all children at any level matching name
230	void getDescendants(const LLStringTableEntry* name, LLXMLNodeList &children) const;
231
232	bool getAttribute(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
233	bool getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
234
235	S32 getLineNumber();
236
237	// The following skip over attributes
238	LLXMLNodePtr getFirstChild() const;
239	LLXMLNodePtr getNextSibling() const;
240
241    LLXMLNodePtr getRoot();
242
243	// Setters
244
245	bool setAttributeString(const char* attr, const std::string& value);
246	
247	void setBoolValue(const BOOL value)	{ setBoolValue(1, &value); }
248	void setByteValue(const U8 value, Encoding encoding = ENCODING_DEFAULT) { setByteValue(1, &value, encoding); }
249	void setIntValue(const S32 value, Encoding encoding = ENCODING_DEFAULT) { setIntValue(1, &value, encoding); }
250	void setUnsignedValue(const U32 value, Encoding encoding = ENCODING_DEFAULT) { setUnsignedValue(1, &value, encoding); }
251	void setLongValue(const U64 value, Encoding encoding = ENCODING_DEFAULT) { setLongValue(1, &value, encoding); }
252	void setFloatValue(const F32 value, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0) { setFloatValue(1, &value, encoding); }
253	void setDoubleValue(const F64 value, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0) { setDoubleValue(1, &value, encoding); }
254	void setStringValue(const std::string& value) { setStringValue(1, &value); }
255	void setUUIDValue(const LLUUID value) { setUUIDValue(1, &value); }
256	void setNodeRefValue(const LLXMLNode *value) { setNodeRefValue(1, &value); }
257
258	void setBoolValue(U32 length, const BOOL *array);
259	void setByteValue(U32 length, const U8 *array, Encoding encoding = ENCODING_DEFAULT);
260	void setIntValue(U32 length, const S32 *array, Encoding encoding = ENCODING_DEFAULT);
261	void setUnsignedValue(U32 length, const U32* array, Encoding encoding = ENCODING_DEFAULT);
262	void setLongValue(U32 length, const U64 *array, Encoding encoding = ENCODING_DEFAULT);
263	void setFloatValue(U32 length, const F32 *array, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0);
264	void setDoubleValue(U32 length, const F64 *array, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0);
265	void setStringValue(U32 length, const std::string *array);
266	void setUUIDValue(U32 length, const LLUUID *array);
267	void setNodeRefValue(U32 length, const LLXMLNode **array);
268	void setValue(const std::string& value);
269	void setName(const std::string& name);
270	void setName(LLStringTableEntry* name);
271
272	void setLineNumber(S32 line_number);
273
274	// Escapes " (quot) ' (apos) & (amp) < (lt) > (gt)
275	static std::string escapeXML(const std::string& xml);
276
277	// Set the default node corresponding to this default node
278	void setDefault(LLXMLNode *default_node);
279
280	// Find the node within defaults_list which corresponds to this node
281	void findDefault(LLXMLNode *defaults_list);
282
283	void updateDefault();
284
285	// Delete any child nodes that aren't among the tree's children, recursive
286	void scrubToTree(LLXMLNode *tree);
287
288	BOOL deleteChildren(const std::string& name);
289	BOOL deleteChildren(LLStringTableEntry* name);
290	void setAttributes(ValueType type, U32 precision, Encoding encoding, U32 length);
291// 	void appendValue(const std::string& value); // Unused
292
293	// Unit Testing
294	void createUnitTest(S32 max_num_children);
295	BOOL performUnitTest(std::string &error_buffer);
296
297protected:
298	BOOL removeChild(LLXMLNode* child);
299
300public:
301	std::string mID;				// The ID attribute of this node
302
303	XML_Parser *mParser;		// Temporary pointer while loading
304
305	BOOL mIsAttribute;			// Flag is only used for output formatting
306	U32 mVersionMajor;			// Version of this tag to use
307	U32 mVersionMinor;
308	U32 mLength;				// If the length is nonzero, then only return arrays of this length
309	U32 mPrecision;				// The number of BITS per array item
310	ValueType mType;			// The value type
311	Encoding mEncoding;			// The value encoding
312	S32 mLineNumber;			// line number in source file, if applicable
313
314	LLXMLNode* mParent;				// The parent node
315	LLXMLChildrenPtr mChildren;		// The child nodes
316	LLXMLAttribList mAttributes;		// The attribute nodes
317	LLXMLNodePtr mPrev;				// Double-linked list previous node
318	LLXMLNodePtr mNext;				// Double-linked list next node
319
320	static BOOL sStripEscapedStrings;
321	static BOOL sStripWhitespaceValues;
322	
323protected:
324	LLStringTableEntry *mName;		// The name of this node
325
326	// The value of this node (use getters/setters only)
327	// Values are not XML-escaped in memory
328	// They may contain " (quot) ' (apos) & (amp) < (lt) > (gt)
329	std::string mValue;
330
331	LLXMLNodePtr mDefault;		// Mirror node in the default tree
332
333	static const char *skipWhitespace(const char *str);
334	static const char *skipNonWhitespace(const char *str);
335	static const char *parseInteger(const char *str, U64 *dest, BOOL *is_negative, U32 precision, Encoding encoding);
336	static const char *parseFloat(const char *str, F64 *dest, U32 precision, Encoding encoding);
337
338	BOOL isFullyDefault();
339};
340
341#endif // LL_LLXMLNODE