Imported existing code

This commit is contained in:
Hazim Gazov
2010-04-02 02:48:44 -03:00
parent 48fbc5ae91
commit 7a86d01598
13996 changed files with 2468699 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
# -*- cmake -*-
project(llxml)
include(00-Common)
include(LLCommon)
include(LLMath)
include(LLXML)
include_directories(
${LLCOMMON_INCLUDE_DIRS}
${LLMATH_INCLUDE_DIRS}
)
set(llxml_SOURCE_FILES
llcontrol.cpp
llxmlnode.cpp
llxmlparser.cpp
llxmltree.cpp
)
set(llxml_HEADER_FILES
CMakeLists.txt
llcontrol.h
llcontrolgroupreader.h
llxmlnode.h
llxmlparser.h
llxmltree.h
)
set_source_files_properties(${llxml_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
list(APPEND llxml_SOURCE_FILES ${llxml_HEADER_FILES})
add_library (llxml ${llxml_SOURCE_FILES})
add_dependencies(llxml prepare)
target_link_libraries(
llxml
${BOOST_SIGNALS_LIBRARY}
${EXPAT_LIBRARIES}
)

1271
indra/llxml/llcontrol.cpp Normal file

File diff suppressed because it is too large Load Diff

245
indra/llxml/llcontrol.h Normal file
View File

@@ -0,0 +1,245 @@
/**
* @file llcontrol.h
* @brief A mechanism for storing "control state" for a program
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLCONTROL_H
#define LL_LLCONTROL_H
#include "llevent.h"
#include "llnametable.h"
#include "llmap.h"
#include "llstring.h"
#include "llrect.h"
#include "llcontrolgroupreader.h"
#include <vector>
// *NOTE: boost::visit_each<> generates warning 4675 on .net 2003
// Disable the warning for the boost includes.
#if LL_WINDOWS
# if (_MSC_VER >= 1300 && _MSC_VER < 1400)
# pragma warning(push)
# pragma warning( disable : 4675 )
# endif
#endif
#include <boost/bind.hpp>
#include <boost/signal.hpp>
#if LL_WINDOWS
# if (_MSC_VER >= 1300 && _MSC_VER < 1400)
# pragma warning(pop)
# endif
#endif
class LLVector3;
class LLVector3d;
class LLColor4;
class LLColor3;
class LLColor4U;
const BOOL NO_PERSIST = FALSE;
typedef enum e_control_type
{
TYPE_U32 = 0,
TYPE_S32,
TYPE_F32,
TYPE_BOOLEAN,
TYPE_STRING,
TYPE_VEC3,
TYPE_VEC3D,
TYPE_RECT,
TYPE_COL4,
TYPE_COL3,
TYPE_COL4U,
TYPE_LLSD,
TYPE_COUNT
} eControlType;
class LLControlVariable : public LLRefCount
{
friend class LLControlGroup;
typedef boost::signal<void(const LLSD&)> signal_t;
private:
std::string mName;
std::string mComment;
eControlType mType;
bool mPersist;
bool mHideFromSettingsEditor;
std::vector<LLSD> mValues;
signal_t mSignal;
public:
LLControlVariable(const std::string& name, eControlType type,
LLSD initial, const std::string& comment,
bool persist = true, bool hidefromsettingseditor = false);
virtual ~LLControlVariable();
const std::string& getName() const { return mName; }
const std::string& getComment() const { return mComment; }
eControlType type() { return mType; }
bool isType(eControlType tp) { return tp == mType; }
void resetToDefault(bool fire_signal = false);
signal_t* getSignal() { return &mSignal; }
bool isDefault() { return (mValues.size() == 1); }
bool isSaveValueDefault();
bool isPersisted() { return mPersist; }
bool isHiddenFromSettingsEditor() { return mHideFromSettingsEditor; }
LLSD get() const { return getValue(); }
LLSD getValue() const { return mValues.back(); }
LLSD getDefault() const { return mValues.front(); }
LLSD getSaveValue() const;
void set(const LLSD& val) { setValue(val); }
void setValue(const LLSD& value, bool saved_value = TRUE);
void setDefaultValue(const LLSD& value);
void setPersist(bool state);
void setHiddenFromSettingsEditor(bool hide);
void setComment(const std::string& comment);
void firePropertyChanged()
{
mSignal(mValues.back());
}
private:
LLSD getComparableValue(const LLSD& value);
bool llsd_compare(const LLSD& a, const LLSD & b);
};
//const U32 STRING_CACHE_SIZE = 10000;
class LLControlGroup : public LLControlGroupReader
{
protected:
typedef std::map<std::string, LLPointer<LLControlVariable> > ctrl_name_table_t;
ctrl_name_table_t mNameTable;
std::set<std::string> mWarnings;
std::string mTypeString[TYPE_COUNT];
eControlType typeStringToEnum(const std::string& typestr);
std::string typeEnumToString(eControlType typeenum);
public:
LLControlGroup();
~LLControlGroup();
void cleanup();
LLPointer<LLControlVariable> getControl(const std::string& name);
struct ApplyFunctor
{
virtual ~ApplyFunctor() {};
virtual void apply(const std::string& name, LLControlVariable* control) = 0;
};
void applyToAll(ApplyFunctor* func);
BOOL declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, BOOL persist, BOOL hidefromsettingseditor = FALSE);
BOOL declareU32(const std::string& name, U32 initial_val, const std::string& comment, BOOL persist = TRUE);
BOOL declareS32(const std::string& name, S32 initial_val, const std::string& comment, BOOL persist = TRUE);
BOOL declareF32(const std::string& name, F32 initial_val, const std::string& comment, BOOL persist = TRUE);
BOOL declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, BOOL persist = TRUE);
BOOL declareString(const std::string& name, const std::string &initial_val, const std::string& comment, BOOL persist = TRUE);
BOOL declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment, BOOL persist = TRUE);
BOOL declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, BOOL persist = TRUE);
BOOL declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, BOOL persist = TRUE);
BOOL declareColor4U(const std::string& name, const LLColor4U &initial_val, const std::string& comment, BOOL persist = TRUE);
BOOL declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, BOOL persist = TRUE);
BOOL declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, BOOL persist = TRUE);
BOOL declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, BOOL persist = TRUE);
std::string findString(const std::string& name);
std::string getString(const std::string& name);
LLWString getWString(const std::string& name);
std::string getText(const std::string& name);
LLVector3 getVector3(const std::string& name);
LLVector3d getVector3d(const std::string& name);
LLRect getRect(const std::string& name);
BOOL getBOOL(const std::string& name);
S32 getS32(const std::string& name);
F32 getF32(const std::string& name);
U32 getU32(const std::string& name);
LLSD getLLSD(const std::string& name);
// Note: If an LLColor4U control exists, it will cast it to the correct
// LLColor4 for you.
LLColor4 getColor(const std::string& name);
LLColor4U getColor4U(const std::string& name);
LLColor4 getColor4(const std::string& name);
LLColor3 getColor3(const std::string& name);
void setBOOL(const std::string& name, BOOL val);
void setS32(const std::string& name, S32 val);
void setF32(const std::string& name, F32 val);
void setU32(const std::string& name, U32 val);
void setString(const std::string& name, const std::string& val);
void setVector3(const std::string& name, const LLVector3 &val);
void setVector3d(const std::string& name, const LLVector3d &val);
void setRect(const std::string& name, const LLRect &val);
void setColor4U(const std::string& name, const LLColor4U &val);
void setColor4(const std::string& name, const LLColor4 &val);
void setColor3(const std::string& name, const LLColor3 &val);
void setLLSD(const std::string& name, const LLSD& val);
void setValue(const std::string& name, const LLSD& val);
BOOL controlExists(const std::string& name);
// Returns number of controls loaded, 0 if failed
// If require_declaration is false, will auto-declare controls it finds
// as the given type.
U32 loadFromFileLegacy(const std::string& filename, BOOL require_declaration = TRUE, eControlType declare_as = TYPE_STRING);
U32 saveToFile(const std::string& filename, BOOL nondefault_only);
U32 loadFromFile(const std::string& filename, bool default_values = false);
void resetToDefaults();
// Ignorable Warnings
// Add a config variable to be reset on resetWarnings()
void addWarning(const std::string& name);
BOOL getWarning(const std::string& name);
void setWarning(const std::string& name, BOOL val);
// Resets all ignorables
void resetWarnings();
};
#endif

View File

@@ -0,0 +1,74 @@
/**
* @file llcontrolgroupreader.h
* @brief Interface providing readonly access to LLControlGroup (intended for unit testing)
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLCONTROLGROUPREADER_H
#define LL_LLCONTROLGROUPREADER_H
#include "stdtypes.h"
#include <string>
// Many of the types below are commented out because for the purposes of the early testing we're doing,
// we don't need them and we don't want to pull in all the machinery to support them.
// But the model is here for future unit test extensions.
class LLControlGroupReader
{
public:
LLControlGroupReader() {}
virtual ~LLControlGroupReader() {}
virtual std::string getString(const std::string& name) = 0;
//virtual LLWString getWString(const std::string& name) = 0;
virtual std::string getText(const std::string& name) = 0;
//virtual LLVector3 getVector3(const std::string& name) = 0;
//virtual LLVector3d getVector3d(const std::string& name) = 0;
//virtual LLRect getRect(const std::string& name) = 0;
virtual BOOL getBOOL(const std::string& name) = 0;
virtual S32 getS32(const std::string& name) = 0;
virtual F32 getF32(const std::string& name) = 0;
virtual U32 getU32(const std::string& name) = 0;
//virtual LLSD getLLSD(const std::string& name) = 0;
//virtual LLColor4 getColor(const std::string& name) = 0;
//virtual LLColor4U getColor4U(const std::string& name) = 0;
//virtual LLColor4 getColor4(const std::string& name) = 0;
//virtual LLColor3 getColor3(const std::string& name) = 0;
};
#endif /* LL_LLCONTROLGROUPREADER_H */

3217
indra/llxml/llxmlnode.cpp Normal file

File diff suppressed because it is too large Load Diff

327
indra/llxml/llxmlnode.h Normal file
View File

@@ -0,0 +1,327 @@
/**
* @file llxmlnode.h
* @brief LLXMLNode definition
*
* $LicenseInfo:firstyear=2000&license=viewergpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLXMLNODE_H
#define LL_LLXMLNODE_H
#ifndef XML_STATIC
#define XML_STATIC 1
#endif
#ifdef LL_STANDALONE
#include <expat.h>
#else
#include "expat/expat.h"
#endif
#include <map>
#include "indra_constants.h"
#include "llmemory.h"
#include "llthread.h"
#include "llstring.h"
#include "llstringtable.h"
class LLVector3;
class LLVector3d;
class LLQuaternion;
class LLUUID;
class LLColor4;
class LLColor4U;
struct CompareAttributes
{
bool operator()(const LLStringTableEntry* const lhs, const LLStringTableEntry* const rhs) const
{
if (lhs == NULL)
return TRUE;
if (rhs == NULL)
return FALSE;
return strcmp(lhs->mString, rhs->mString) < 0;
}
};
// Defines a simple node hierarchy for reading and writing task objects
class LLXMLNode;
typedef LLPointer<LLXMLNode> LLXMLNodePtr;
typedef std::multimap<std::string, LLXMLNodePtr > LLXMLNodeList;
typedef std::multimap<const LLStringTableEntry *, LLXMLNodePtr > LLXMLChildList;
typedef std::map<const LLStringTableEntry *, LLXMLNodePtr, CompareAttributes> LLXMLAttribList;
class LLColor4;
class LLColor4U;
class LLQuaternion;
class LLVector3;
class LLVector3d;
class LLVector4;
class LLVector4U;
struct LLXMLChildren : public LLThreadSafeRefCount
{
LLXMLChildList map; // Map of children names->pointers
LLXMLNodePtr head; // Head of the double-linked list
LLXMLNodePtr tail; // Tail of the double-linked list
};
typedef LLPointer<LLXMLChildren> LLXMLChildrenPtr;
class LLXMLNode : public LLThreadSafeRefCount
{
public:
enum ValueType
{
TYPE_CONTAINER, // A node which contains nodes
TYPE_UNKNOWN, // A node loaded from file without a specified type
TYPE_BOOLEAN, // "true" or "false"
TYPE_INTEGER, // any integer type: U8, U32, S32, U64, etc.
TYPE_FLOAT, // any floating point type: F32, F64
TYPE_STRING, // a string
TYPE_UUID, // a UUID
TYPE_NODEREF, // the ID of another node in the hierarchy to reference
};
enum Encoding
{
ENCODING_DEFAULT = 0,
ENCODING_DECIMAL,
ENCODING_HEX,
// ENCODING_BASE32, // Not implemented yet
};
protected:
~LLXMLNode();
public:
LLXMLNode();
LLXMLNode(const char* name, BOOL is_attribute);
LLXMLNode(LLStringTableEntry* name, BOOL is_attribute);
LLXMLNode(const LLXMLNode& rhs);
LLXMLNodePtr deepCopy();
BOOL isNull();
BOOL deleteChild(LLXMLNode* child);
void addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child = LLXMLNodePtr(NULL));
void setParent(LLXMLNodePtr new_parent); // reparent if necessary
// Serialization
static bool parseFile(
const std::string& filename,
LLXMLNodePtr& node,
LLXMLNode* defaults_tree);
static bool parseBuffer(
U8* buffer,
U32 length,
LLXMLNodePtr& node,
LLXMLNode* defaults);
static bool parseStream(
std::istream& str,
LLXMLNodePtr& node,
LLXMLNode* defaults);
static bool updateNode(
LLXMLNodePtr& node,
LLXMLNodePtr& update_node);
static LLXMLNodePtr replaceNode(LLXMLNodePtr node, LLXMLNodePtr replacement_node);
static void writeHeaderToFile(LLFILE *fOut);
void writeToFile(LLFILE *fOut, const std::string& indent = std::string());
void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string());
// Utility
void findName(const std::string& name, LLXMLNodeList &results);
void findName(LLStringTableEntry* name, LLXMLNodeList &results);
void findID(const std::string& id, LLXMLNodeList &results);
virtual LLXMLNodePtr createChild(const char* name, BOOL is_attribute);
virtual LLXMLNodePtr createChild(LLStringTableEntry* name, BOOL is_attribute);
// Getters
U32 getBoolValue(U32 expected_length, BOOL *array);
U32 getByteValue(U32 expected_length, U8 *array, Encoding encoding = ENCODING_DEFAULT);
U32 getIntValue(U32 expected_length, S32 *array, Encoding encoding = ENCODING_DEFAULT);
U32 getUnsignedValue(U32 expected_length, U32 *array, Encoding encoding = ENCODING_DEFAULT);
U32 getLongValue(U32 expected_length, U64 *array, Encoding encoding = ENCODING_DEFAULT);
U32 getFloatValue(U32 expected_length, F32 *array, Encoding encoding = ENCODING_DEFAULT);
U32 getDoubleValue(U32 expected_length, F64 *array, Encoding encoding = ENCODING_DEFAULT);
U32 getStringValue(U32 expected_length, std::string *array);
U32 getUUIDValue(U32 expected_length, LLUUID *array);
U32 getNodeRefValue(U32 expected_length, LLXMLNode **array);
BOOL hasAttribute(const char* name );
// these are designed to be more generic versions of the functions
// rather than relying on LL-types
bool getAttribute_bool(const char* name, bool& value );
BOOL getAttributeBOOL(const char* name, BOOL& value );
BOOL getAttributeU8(const char* name, U8& value );
BOOL getAttributeS8(const char* name, S8& value );
BOOL getAttributeU16(const char* name, U16& value );
BOOL getAttributeS16(const char* name, S16& value );
BOOL getAttributeU32(const char* name, U32& value );
BOOL getAttributeS32(const char* name, S32& value );
BOOL getAttributeF32(const char* name, F32& value );
BOOL getAttributeF64(const char* name, F64& value );
BOOL getAttributeColor(const char* name, LLColor4& value );
BOOL getAttributeColor4(const char* name, LLColor4& value );
BOOL getAttributeColor4U(const char* name, LLColor4U& value );
BOOL getAttributeVector3(const char* name, LLVector3& value );
BOOL getAttributeVector3d(const char* name, LLVector3d& value );
BOOL getAttributeQuat(const char* name, LLQuaternion& value );
BOOL getAttributeUUID(const char* name, LLUUID& value );
BOOL getAttributeString(const char* name, std::string& value );
const ValueType& getType() const { return mType; }
U32 getLength() const { return mLength; }
U32 getPrecision() const { return mPrecision; }
const std::string& getValue() const { return mValue; }
std::string getTextContents() const;
const LLStringTableEntry* getName() const { return mName; }
BOOL hasName(const char* name) const { return mName == gStringTable.checkStringEntry(name); }
BOOL hasName(const std::string& name) const { return mName == gStringTable.checkStringEntry(name.c_str()); }
const std::string& getID() const { return mID; }
U32 getChildCount() const;
// getChild returns a Null LLXMLNode (not a NULL pointer) if there is no such child.
// This child has no value so any getTYPEValue() calls on it will return 0.
bool getChild(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
bool getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
void getChildren(const char* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const;
void getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const;
// recursively finds all children at any level matching name
void getDescendants(const LLStringTableEntry* name, LLXMLNodeList &children) const;
bool getAttribute(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
bool getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
// The following skip over attributes
LLXMLNodePtr getFirstChild() const;
LLXMLNodePtr getNextSibling() const;
LLXMLNodePtr getRoot();
// Setters
bool setAttributeString(const char* attr, const std::string& value);
void setBoolValue(const BOOL value) { setBoolValue(1, &value); }
void setByteValue(const U8 value, Encoding encoding = ENCODING_DEFAULT) { setByteValue(1, &value, encoding); }
void setIntValue(const S32 value, Encoding encoding = ENCODING_DEFAULT) { setIntValue(1, &value, encoding); }
void setUnsignedValue(const U32 value, Encoding encoding = ENCODING_DEFAULT) { setUnsignedValue(1, &value, encoding); }
void setLongValue(const U64 value, Encoding encoding = ENCODING_DEFAULT) { setLongValue(1, &value, encoding); }
void setFloatValue(const F32 value, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0) { setFloatValue(1, &value, encoding); }
void setDoubleValue(const F64 value, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0) { setDoubleValue(1, &value, encoding); }
void setStringValue(const std::string& value) { setStringValue(1, &value); }
void setUUIDValue(const LLUUID value) { setUUIDValue(1, &value); }
void setNodeRefValue(const LLXMLNode *value) { setNodeRefValue(1, &value); }
void setBoolValue(U32 length, const BOOL *array);
void setByteValue(U32 length, const U8 *array, Encoding encoding = ENCODING_DEFAULT);
void setIntValue(U32 length, const S32 *array, Encoding encoding = ENCODING_DEFAULT);
void setUnsignedValue(U32 length, const U32* array, Encoding encoding = ENCODING_DEFAULT);
void setLongValue(U32 length, const U64 *array, Encoding encoding = ENCODING_DEFAULT);
void setFloatValue(U32 length, const F32 *array, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0);
void setDoubleValue(U32 length, const F64 *array, Encoding encoding = ENCODING_DEFAULT, U32 precision = 0);
void setStringValue(U32 length, const std::string *array);
void setUUIDValue(U32 length, const LLUUID *array);
void setNodeRefValue(U32 length, const LLXMLNode **array);
void setValue(const std::string& value);
void setName(const std::string& name);
void setName(LLStringTableEntry* name);
// Escapes " (quot) ' (apos) & (amp) < (lt) > (gt)
static std::string escapeXML(const std::string& xml);
// Set the default node corresponding to this default node
void setDefault(LLXMLNode *default_node);
// Find the node within defaults_list which corresponds to this node
void findDefault(LLXMLNode *defaults_list);
void updateDefault();
// Delete any child nodes that aren't among the tree's children, recursive
void scrubToTree(LLXMLNode *tree);
BOOL deleteChildren(const std::string& name);
BOOL deleteChildren(LLStringTableEntry* name);
void setAttributes(ValueType type, U32 precision, Encoding encoding, U32 length);
// void appendValue(const std::string& value); // Unused
// Unit Testing
void createUnitTest(S32 max_num_children);
BOOL performUnitTest(std::string &error_buffer);
protected:
BOOL removeChild(LLXMLNode* child);
public:
std::string mID; // The ID attribute of this node
XML_Parser *mParser; // Temporary pointer while loading
BOOL mIsAttribute; // Flag is only used for output formatting
U32 mVersionMajor; // Version of this tag to use
U32 mVersionMinor;
U32 mLength; // If the length is nonzero, then only return arrays of this length
U32 mPrecision; // The number of BITS per array item
ValueType mType; // The value type
Encoding mEncoding; // The value encoding
LLXMLNode* mParent; // The parent node
LLXMLChildrenPtr mChildren; // The child nodes
LLXMLAttribList mAttributes; // The attribute nodes
LLXMLNodePtr mPrev; // Double-linked list previous node
LLXMLNodePtr mNext; // Double-linked list next node
static BOOL sStripEscapedStrings;
static BOOL sStripWhitespaceValues;
protected:
LLStringTableEntry *mName; // The name of this node
std::string mValue; // The value of this node (use getters/setters only)
LLXMLNodePtr mDefault; // Mirror node in the default tree
static const char *skipWhitespace(const char *str);
static const char *skipNonWhitespace(const char *str);
static const char *parseInteger(const char *str, U64 *dest, BOOL *is_negative, U32 precision, Encoding encoding);
static const char *parseFloat(const char *str, F64 *dest, U32 precision, Encoding encoding);
BOOL isFullyDefault();
};
#endif // LL_LLXMLNODE

422
indra/llxml/llxmlparser.cpp Normal file
View File

@@ -0,0 +1,422 @@
/**
* @file llxmlparser.cpp
* @brief LLXmlParser implementation
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
// llxmlparser.cpp
//
// copyright 2002, linden research inc
#include "linden_common.h"
#include "llxmlparser.h"
#include "llerror.h"
LLXmlParser::LLXmlParser()
:
mParser( NULL ),
mDepth( 0 )
{
mAuxErrorString = "no error";
// Override the document's declared encoding.
mParser = XML_ParserCreate(NULL);
XML_SetUserData(mParser, this);
XML_SetElementHandler( mParser, startElementHandler, endElementHandler);
XML_SetCharacterDataHandler( mParser, characterDataHandler);
XML_SetProcessingInstructionHandler( mParser, processingInstructionHandler);
XML_SetCommentHandler( mParser, commentHandler);
XML_SetCdataSectionHandler( mParser, startCdataSectionHandler, endCdataSectionHandler);
// This sets the default handler but does not inhibit expansion of internal entities.
// The entity reference will not be passed to the default handler.
XML_SetDefaultHandlerExpand( mParser, defaultDataHandler);
XML_SetUnparsedEntityDeclHandler( mParser, unparsedEntityDeclHandler);
}
LLXmlParser::~LLXmlParser()
{
XML_ParserFree( mParser );
}
BOOL LLXmlParser::parseFile(const std::string &path)
{
llassert( !mDepth );
BOOL success = TRUE;
LLFILE* file = LLFile::fopen(path, "rb"); /* Flawfinder: ignore */
if( !file )
{
mAuxErrorString = llformat( "Couldn't open file %s", path.c_str());
success = FALSE;
}
else
{
S32 bytes_read = 0;
fseek(file, 0L, SEEK_END);
S32 buffer_size = ftell(file);
fseek(file, 0L, SEEK_SET);
void* buffer = XML_GetBuffer(mParser, buffer_size);
if( !buffer )
{
mAuxErrorString = llformat( "Unable to allocate XML buffer while reading file %s", path.c_str() );
success = FALSE;
goto exit_label;
}
bytes_read = (S32)fread(buffer, 1, buffer_size, file);
if( bytes_read <= 0 )
{
mAuxErrorString = llformat( "Error while reading file %s", path.c_str() );
success = FALSE;
goto exit_label;
}
if( !XML_ParseBuffer(mParser, bytes_read, TRUE ) )
{
mAuxErrorString = llformat( "Error while parsing file %s", path.c_str() );
success = FALSE;
}
exit_label:
fclose( file );
}
if( success )
{
llassert( !mDepth );
}
mDepth = 0;
if( !success )
{
llwarns << mAuxErrorString << llendl;
}
return success;
}
// Parses some input. Returns 0 if a fatal error is detected.
// The last call must have isFinal true;
// len may be zero for this call (or any other).
S32 LLXmlParser::parse( const char* buf, int len, int isFinal )
{
return XML_Parse(mParser, buf, len, isFinal);
}
const char* LLXmlParser::getErrorString()
{
const char* error_string = XML_ErrorString(XML_GetErrorCode( mParser ));
if( !error_string )
{
error_string = mAuxErrorString.c_str();
}
return error_string;
}
S32 LLXmlParser::getCurrentLineNumber()
{
return XML_GetCurrentLineNumber( mParser );
}
S32 LLXmlParser::getCurrentColumnNumber()
{
return XML_GetCurrentColumnNumber(mParser);
}
///////////////////////////////////////////////////////////////////////////////
// Pseudo-private methods. These are only used by internal callbacks.
// static
void LLXmlParser::startElementHandler(
void *userData,
const XML_Char *name,
const XML_Char **atts)
{
LLXmlParser* self = (LLXmlParser*) userData;
self->startElement( name, atts );
self->mDepth++;
}
// static
void LLXmlParser::endElementHandler(
void *userData,
const XML_Char *name)
{
LLXmlParser* self = (LLXmlParser*) userData;
self->mDepth--;
self->endElement( name );
}
// s is not 0 terminated.
// static
void LLXmlParser::characterDataHandler(
void *userData,
const XML_Char *s,
int len)
{
LLXmlParser* self = (LLXmlParser*) userData;
self->characterData( s, len );
}
// target and data are 0 terminated
// static
void LLXmlParser::processingInstructionHandler(
void *userData,
const XML_Char *target,
const XML_Char *data)
{
LLXmlParser* self = (LLXmlParser*) userData;
self->processingInstruction( target, data );
}
// data is 0 terminated
// static
void LLXmlParser::commentHandler(void *userData, const XML_Char *data)
{
LLXmlParser* self = (LLXmlParser*) userData;
self->comment( data );
}
// static
void LLXmlParser::startCdataSectionHandler(void *userData)
{
LLXmlParser* self = (LLXmlParser*) userData;
self->mDepth++;
self->startCdataSection();
}
// static
void LLXmlParser::endCdataSectionHandler(void *userData)
{
LLXmlParser* self = (LLXmlParser*) userData;
self->endCdataSection();
self->mDepth++;
}
// This is called for any characters in the XML document for
// which there is no applicable handler. This includes both
// characters that are part of markup which is of a kind that is
// not reported (comments, markup declarations), or characters
// that are part of a construct which could be reported but
// for which no handler has been supplied. The characters are passed
// exactly as they were in the XML document except that
// they will be encoded in UTF-8. Line boundaries are not normalized.
// Note that a byte order mark character is not passed to the default handler.
// There are no guarantees about how characters are divided between calls
// to the default handler: for example, a comment might be split between
// multiple calls.
// static
void LLXmlParser::defaultDataHandler(
void *userData,
const XML_Char *s,
int len)
{
LLXmlParser* self = (LLXmlParser*) userData;
self->defaultData( s, len );
}
// This is called for a declaration of an unparsed (NDATA)
// entity. The base argument is whatever was set by XML_SetBase.
// The entityName, systemId and notationName arguments will never be null.
// The other arguments may be.
// static
void LLXmlParser::unparsedEntityDeclHandler(
void *userData,
const XML_Char *entityName,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId,
const XML_Char *notationName)
{
LLXmlParser* self = (LLXmlParser*) userData;
self->unparsedEntityDecl( entityName, base, systemId, publicId, notationName );
}
////////////////////////////////////////////////////////////////////
// Test code.
/*
class LLXmlDOMParser : public LLXmlParser
{
public:
LLXmlDOMParser() {}
virtual ~LLXmlDOMParser() {}
void tabs()
{
for ( int i = 0; i < getDepth(); i++)
{
putchar(' ');
}
}
virtual void startElement(const char *name, const char **atts)
{
tabs();
printf("startElement %s\n", name);
S32 i = 0;
while( atts[i] && atts[i+1] )
{
tabs();
printf( "\t%s=%s\n", atts[i], atts[i+1] );
i += 2;
}
if( atts[i] )
{
tabs();
printf( "\ttrailing attribute: %s\n", atts[i] );
}
}
virtual void endElement(const char *name)
{
tabs();
printf("endElement %s\n", name);
}
virtual void characterData(const char *s, int len)
{
tabs();
char* str = new char[len+1];
strncpy( str, s, len );
str[len] = '\0';
printf("CharacterData %s\n", str);
delete str;
}
virtual void processingInstruction(const char *target, const char *data)
{
tabs();
printf("processingInstruction %s\n", data);
}
virtual void comment(const char *data)
{
tabs();
printf("comment %s\n", data);
}
virtual void startCdataSection()
{
tabs();
printf("startCdataSection\n");
}
virtual void endCdataSection()
{
tabs();
printf("endCdataSection\n");
}
virtual void defaultData(const char *s, int len)
{
tabs();
char* str = new char[len+1];
strncpy( str, s, len );
str[len] = '\0';
printf("defaultData %s\n", str);
delete str;
}
virtual void unparsedEntityDecl(
const char *entityName,
const char *base,
const char *systemId,
const char *publicId,
const char *notationName)
{
tabs();
printf(
"unparsed entity:\n"
"\tentityName %s\n"
"\tbase %s\n"
"\tsystemId %s\n"
"\tpublicId %s\n"
"\tnotationName %s\n",
entityName,
base,
systemId,
publicId,
notationName );
}
};
int main()
{
char buf[1024];
LLFILE* file = LLFile::fopen("test.xml", "rb");
if( !file )
{
return 1;
}
LLXmlDOMParser parser;
int done;
do {
size_t len = fread(buf, 1, sizeof(buf), file);
done = len < sizeof(buf);
if( 0 == parser.parse( buf, len, done) )
{
fprintf(stderr,
"%s at line %d\n",
parser.getErrorString(),
parser.getCurrentLineNumber() );
return 1;
}
} while (!done);
fclose( file );
return 0;
}
*/

139
indra/llxml/llxmlparser.h Normal file
View File

@@ -0,0 +1,139 @@
/**
* @file llxmlparser.h
* @brief LLXmlParser class definition
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLXMLPARSER_H
#define LL_LLXMLPARSER_H
#ifndef XML_STATIC
#define XML_STATIC 1
#endif
#ifdef LL_STANDALONE
#include <expat.h>
#else
#include "expat/expat.h"
#endif
class LLXmlParser
{
public:
LLXmlParser();
virtual ~LLXmlParser();
// Parses entire file
BOOL parseFile(const std::string &path);
// Parses some input. Returns 0 if a fatal error is detected.
// The last call must have isFinal true;
// len may be zero for this call (or any other).
S32 parse( const char* buf, int len, int isFinal );
const char* getErrorString();
S32 getCurrentLineNumber();
S32 getCurrentColumnNumber();
S32 getDepth() { return mDepth; }
protected:
// atts is array of name/value pairs, terminated by 0;
// names and values are 0 terminated.
virtual void startElement(const char *name, const char **atts) {}
virtual void endElement(const char *name) {}
// s is not 0 terminated.
virtual void characterData(const char *s, int len) {}
// target and data are 0 terminated
virtual void processingInstruction(const char *target, const char *data) {}
// data is 0 terminated
virtual void comment(const char *data) {}
virtual void startCdataSection() {}
virtual void endCdataSection() {}
// This is called for any characters in the XML document for
// which there is no applicable handler. This includes both
// characters that are part of markup which is of a kind that is
// not reported (comments, markup declarations), or characters
// that are part of a construct which could be reported but
// for which no handler has been supplied. The characters are passed
// exactly as they were in the XML document except that
// they will be encoded in UTF-8. Line boundaries are not normalized.
// Note that a byte order mark character is not passed to the default handler.
// There are no guarantees about how characters are divided between calls
// to the default handler: for example, a comment might be split between
// multiple calls.
virtual void defaultData(const char *s, int len) {}
// This is called for a declaration of an unparsed (NDATA)
// entity. The base argument is whatever was set by XML_SetBase.
// The entityName, systemId and notationName arguments will never be null.
// The other arguments may be.
virtual void unparsedEntityDecl(
const char *entityName,
const char *base,
const char *systemId,
const char *publicId,
const char *notationName) {}
public:
///////////////////////////////////////////////////////////////////////////////
// Pseudo-private methods. These are only used by internal callbacks.
static void startElementHandler(void *userData, const XML_Char *name, const XML_Char **atts);
static void endElementHandler(void *userData, const XML_Char *name);
static void characterDataHandler(void *userData, const XML_Char *s, int len);
static void processingInstructionHandler(void *userData, const XML_Char *target, const XML_Char *data);
static void commentHandler(void *userData, const XML_Char *data);
static void startCdataSectionHandler(void *userData);
static void endCdataSectionHandler(void *userData);
static void defaultDataHandler( void *userData, const XML_Char *s, int len);
static void unparsedEntityDeclHandler(
void *userData,
const XML_Char *entityName,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId,
const XML_Char *notationName);
protected:
XML_Parser mParser;
int mDepth;
std::string mAuxErrorString;
};
#endif // LL_LLXMLPARSER_H

697
indra/llxml/llxmltree.cpp Normal file
View File

@@ -0,0 +1,697 @@
/**
* @file llxmltree.cpp
* @brief LLXmlTree implementation
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llxmltree.h"
#include "v3color.h"
#include "v4color.h"
#include "v4coloru.h"
#include "v3math.h"
#include "v3dmath.h"
#include "v4math.h"
#include "llquaternion.h"
#include "lluuid.h"
//////////////////////////////////////////////////////////////
// LLXmlTree
// static
LLStdStringTable LLXmlTree::sAttributeKeys(1024);
LLXmlTree::LLXmlTree()
: mRoot( NULL ),
mNodeNames(512)
{
}
LLXmlTree::~LLXmlTree()
{
cleanup();
}
void LLXmlTree::cleanup()
{
delete mRoot;
mRoot = NULL;
mNodeNames.cleanup();
}
BOOL LLXmlTree::parseFile(const std::string &path, BOOL keep_contents)
{
delete mRoot;
mRoot = NULL;
LLXmlTreeParser parser(this);
BOOL success = parser.parseFile( path, &mRoot, keep_contents );
if( !success )
{
S32 line_number = parser.getCurrentLineNumber();
const char* error = parser.getErrorString();
llwarns << "LLXmlTree parse failed. Line " << line_number << ": " << error << llendl;
}
return success;
}
void LLXmlTree::dump()
{
if( mRoot )
{
dumpNode( mRoot, " " );
}
}
void LLXmlTree::dumpNode( LLXmlTreeNode* node, const std::string& prefix )
{
node->dump( prefix );
std::string new_prefix = prefix + " ";
for( LLXmlTreeNode* child = node->getFirstChild(); child; child = node->getNextChild() )
{
dumpNode( child, new_prefix );
}
}
//////////////////////////////////////////////////////////////
// LLXmlTreeNode
LLXmlTreeNode::LLXmlTreeNode( const std::string& name, LLXmlTreeNode* parent, LLXmlTree* tree )
: mName(name),
mParent(parent),
mTree(tree)
{
}
LLXmlTreeNode::~LLXmlTreeNode()
{
attribute_map_t::iterator iter;
for (iter=mAttributes.begin(); iter != mAttributes.end(); iter++)
delete iter->second;
child_list_t::iterator child_iter;
for (child_iter=mChildList.begin(); child_iter != mChildList.end(); child_iter++)
delete *child_iter;
}
void LLXmlTreeNode::dump( const std::string& prefix )
{
llinfos << prefix << mName ;
if( !mContents.empty() )
{
llcont << " contents = \"" << mContents << "\"";
}
attribute_map_t::iterator iter;
for (iter=mAttributes.begin(); iter != mAttributes.end(); iter++)
{
LLStdStringHandle key = iter->first;
const std::string* value = iter->second;
llcont << prefix << " " << key << "=" << (value->empty() ? "NULL" : *value);
}
llcont << llendl;
}
BOOL LLXmlTreeNode::hasAttribute(const std::string& name)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
attribute_map_t::iterator iter = mAttributes.find(canonical_name);
return (iter == mAttributes.end()) ? false : true;
}
void LLXmlTreeNode::addAttribute(const std::string& name, const std::string& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
const std::string *newstr = new std::string(value);
mAttributes[canonical_name] = newstr; // insert + copy
}
LLXmlTreeNode* LLXmlTreeNode::getFirstChild()
{
mChildListIter = mChildList.begin();
return getNextChild();
}
LLXmlTreeNode* LLXmlTreeNode::getNextChild()
{
if (mChildListIter == mChildList.end())
return 0;
else
return *mChildListIter++;
}
LLXmlTreeNode* LLXmlTreeNode::getChildByName(const std::string& name)
{
LLStdStringHandle tableptr = mTree->mNodeNames.checkString(name);
mChildMapIter = mChildMap.lower_bound(tableptr);
mChildMapEndIter = mChildMap.upper_bound(tableptr);
return getNextNamedChild();
}
LLXmlTreeNode* LLXmlTreeNode::getNextNamedChild()
{
if (mChildMapIter == mChildMapEndIter)
return NULL;
else
return (mChildMapIter++)->second;
}
void LLXmlTreeNode::appendContents(const std::string& str)
{
mContents.append( str );
}
void LLXmlTreeNode::addChild(LLXmlTreeNode* child)
{
llassert( child );
mChildList.push_back( child );
// Add a name mapping to this node
LLStdStringHandle tableptr = mTree->mNodeNames.insert(child->mName);
mChildMap.insert( child_map_t::value_type(tableptr, child));
child->mParent = this;
}
//////////////////////////////////////////////////////////////
// These functions assume that name is already in mAttritrubteKeys
BOOL LLXmlTreeNode::getFastAttributeBOOL(LLStdStringHandle canonical_name, BOOL& value)
{
const std::string *s = getAttribute( canonical_name );
return s && LLStringUtil::convertToBOOL( *s, value );
}
BOOL LLXmlTreeNode::getFastAttributeU8(LLStdStringHandle canonical_name, U8& value)
{
const std::string *s = getAttribute( canonical_name );
return s && LLStringUtil::convertToU8( *s, value );
}
BOOL LLXmlTreeNode::getFastAttributeS8(LLStdStringHandle canonical_name, S8& value)
{
const std::string *s = getAttribute( canonical_name );
return s && LLStringUtil::convertToS8( *s, value );
}
BOOL LLXmlTreeNode::getFastAttributeS16(LLStdStringHandle canonical_name, S16& value)
{
const std::string *s = getAttribute( canonical_name );
return s && LLStringUtil::convertToS16( *s, value );
}
BOOL LLXmlTreeNode::getFastAttributeU16(LLStdStringHandle canonical_name, U16& value)
{
const std::string *s = getAttribute( canonical_name );
return s && LLStringUtil::convertToU16( *s, value );
}
BOOL LLXmlTreeNode::getFastAttributeU32(LLStdStringHandle canonical_name, U32& value)
{
const std::string *s = getAttribute( canonical_name );
return s && LLStringUtil::convertToU32( *s, value );
}
BOOL LLXmlTreeNode::getFastAttributeS32(LLStdStringHandle canonical_name, S32& value)
{
const std::string *s = getAttribute( canonical_name );
return s && LLStringUtil::convertToS32( *s, value );
}
BOOL LLXmlTreeNode::getFastAttributeF32(LLStdStringHandle canonical_name, F32& value)
{
const std::string *s = getAttribute( canonical_name );
return s && LLStringUtil::convertToF32( *s, value );
}
BOOL LLXmlTreeNode::getFastAttributeF64(LLStdStringHandle canonical_name, F64& value)
{
const std::string *s = getAttribute( canonical_name );
return s && LLStringUtil::convertToF64( *s, value );
}
BOOL LLXmlTreeNode::getFastAttributeColor(LLStdStringHandle canonical_name, LLColor4& value)
{
const std::string *s = getAttribute( canonical_name );
return s ? LLColor4::parseColor(*s, &value) : FALSE;
}
BOOL LLXmlTreeNode::getFastAttributeColor4(LLStdStringHandle canonical_name, LLColor4& value)
{
const std::string *s = getAttribute( canonical_name );
return s ? LLColor4::parseColor4(*s, &value) : FALSE;
}
BOOL LLXmlTreeNode::getFastAttributeColor4U(LLStdStringHandle canonical_name, LLColor4U& value)
{
const std::string *s = getAttribute( canonical_name );
return s ? LLColor4U::parseColor4U(*s, &value ) : FALSE;
}
BOOL LLXmlTreeNode::getFastAttributeVector3(LLStdStringHandle canonical_name, LLVector3& value)
{
const std::string *s = getAttribute( canonical_name );
return s ? LLVector3::parseVector3(*s, &value ) : FALSE;
}
BOOL LLXmlTreeNode::getFastAttributeVector3d(LLStdStringHandle canonical_name, LLVector3d& value)
{
const std::string *s = getAttribute( canonical_name );
return s ? LLVector3d::parseVector3d(*s, &value ) : FALSE;
}
BOOL LLXmlTreeNode::getFastAttributeQuat(LLStdStringHandle canonical_name, LLQuaternion& value)
{
const std::string *s = getAttribute( canonical_name );
return s ? LLQuaternion::parseQuat(*s, &value ) : FALSE;
}
BOOL LLXmlTreeNode::getFastAttributeUUID(LLStdStringHandle canonical_name, LLUUID& value)
{
const std::string *s = getAttribute( canonical_name );
return s ? LLUUID::parseUUID(*s, &value ) : FALSE;
}
BOOL LLXmlTreeNode::getFastAttributeString(LLStdStringHandle canonical_name, std::string& value)
{
const std::string *s = getAttribute( canonical_name );
if( !s )
{
return FALSE;
}
value = *s;
return TRUE;
}
//////////////////////////////////////////////////////////////
BOOL LLXmlTreeNode::getAttributeBOOL(const std::string& name, BOOL& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeBOOL(canonical_name, value);
}
BOOL LLXmlTreeNode::getAttributeU8(const std::string& name, U8& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeU8(canonical_name, value);
}
BOOL LLXmlTreeNode::getAttributeS8(const std::string& name, S8& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeS8(canonical_name, value);
}
BOOL LLXmlTreeNode::getAttributeS16(const std::string& name, S16& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeS16(canonical_name, value);
}
BOOL LLXmlTreeNode::getAttributeU16(const std::string& name, U16& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeU16(canonical_name, value);
}
BOOL LLXmlTreeNode::getAttributeU32(const std::string& name, U32& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeU32(canonical_name, value);
}
BOOL LLXmlTreeNode::getAttributeS32(const std::string& name, S32& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeS32(canonical_name, value);
}
BOOL LLXmlTreeNode::getAttributeF32(const std::string& name, F32& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeF32(canonical_name, value);
}
BOOL LLXmlTreeNode::getAttributeF64(const std::string& name, F64& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeF64(canonical_name, value);
}
BOOL LLXmlTreeNode::getAttributeColor(const std::string& name, LLColor4& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeColor(canonical_name, value);
}
BOOL LLXmlTreeNode::getAttributeColor4(const std::string& name, LLColor4& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeColor4(canonical_name, value);
}
BOOL LLXmlTreeNode::getAttributeColor4U(const std::string& name, LLColor4U& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeColor4U(canonical_name, value);
}
BOOL LLXmlTreeNode::getAttributeVector3(const std::string& name, LLVector3& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeVector3(canonical_name, value);
}
BOOL LLXmlTreeNode::getAttributeVector3d(const std::string& name, LLVector3d& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeVector3d(canonical_name, value);
}
BOOL LLXmlTreeNode::getAttributeQuat(const std::string& name, LLQuaternion& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeQuat(canonical_name, value);
}
BOOL LLXmlTreeNode::getAttributeUUID(const std::string& name, LLUUID& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeUUID(canonical_name, value);
}
BOOL LLXmlTreeNode::getAttributeString(const std::string& name, std::string& value)
{
LLStdStringHandle canonical_name = LLXmlTree::sAttributeKeys.addString( name );
return getFastAttributeString(canonical_name, value);
}
/*
The following xml <message> nodes will all return the string from getTextContents():
"The quick brown fox\n Jumps over the lazy dog"
1. HTML paragraph format:
<message>
<p>The quick brown fox</p>
<p> Jumps over the lazy dog</p>
</message>
2. Each quoted section -> paragraph:
<message>
"The quick brown fox"
" Jumps over the lazy dog"
</message>
3. Literal text with beginning and trailing whitespace removed:
<message>
The quick brown fox
Jumps over the lazy dog
</message>
*/
std::string LLXmlTreeNode::getTextContents()
{
std::string msg;
LLXmlTreeNode* p = getChildByName("p");
if (p)
{
// Case 1: node has <p>text</p> tags
while (p)
{
msg += p->getContents() + "\n";
p = getNextNamedChild();
}
}
else
{
std::string::size_type n = mContents.find_first_not_of(" \t\n");
if (n != std::string::npos && mContents[n] == '\"')
{
// Case 2: node has quoted text
S32 num_lines = 0;
while(1)
{
// mContents[n] == '"'
++n;
std::string::size_type t = n;
std::string::size_type m = 0;
// fix-up escaped characters
while(1)
{
m = mContents.find_first_of("\\\"", t); // find first \ or "
if ((m == std::string::npos) || (mContents[m] == '\"'))
{
break;
}
mContents.erase(m,1);
t = m+1;
}
if (m == std::string::npos)
{
break;
}
// mContents[m] == '"'
num_lines++;
msg += mContents.substr(n,m-n) + "\n";
n = mContents.find_first_of("\"", m+1);
if (n == std::string::npos)
{
if (num_lines == 1)
{
msg.erase(msg.size()-1); // remove "\n" if only one line
}
break;
}
}
}
else
{
// Case 3: node has embedded text (beginning and trailing whitespace trimmed)
msg = mContents;
}
}
return msg;
}
//////////////////////////////////////////////////////////////
// LLXmlTreeParser
LLXmlTreeParser::LLXmlTreeParser(LLXmlTree* tree)
: mTree(tree),
mRoot( NULL ),
mCurrent( NULL ),
mDump( FALSE )
{
}
LLXmlTreeParser::~LLXmlTreeParser()
{
}
BOOL LLXmlTreeParser::parseFile(const std::string &path, LLXmlTreeNode** root, BOOL keep_contents)
{
llassert( !mRoot );
llassert( !mCurrent );
mKeepContents = keep_contents;
BOOL success = LLXmlParser::parseFile(path);
*root = mRoot;
mRoot = NULL;
if( success )
{
llassert( !mCurrent );
}
mCurrent = NULL;
return success;
}
const std::string& LLXmlTreeParser::tabs()
{
static std::string s;
s = "";
S32 num_tabs = getDepth() - 1;
for( S32 i = 0; i < num_tabs; i++)
{
s += " ";
}
return s;
}
void LLXmlTreeParser::startElement(const char* name, const char **atts)
{
if( mDump )
{
llinfos << tabs() << "startElement " << name << llendl;
S32 i = 0;
while( atts[i] && atts[i+1] )
{
llinfos << tabs() << "attribute: " << atts[i] << "=" << atts[i+1] << llendl;
i += 2;
}
}
LLXmlTreeNode* child = CreateXmlTreeNode( std::string(name), mCurrent );
S32 i = 0;
while( atts[i] && atts[i+1] )
{
child->addAttribute( atts[i], atts[i+1] );
i += 2;
}
if( mCurrent )
{
mCurrent->addChild( child );
}
else
{
llassert( !mRoot );
mRoot = child;
}
mCurrent = child;
}
LLXmlTreeNode* LLXmlTreeParser::CreateXmlTreeNode(const std::string& name, LLXmlTreeNode* parent)
{
return new LLXmlTreeNode(name, parent, mTree);
}
void LLXmlTreeParser::endElement(const char* name)
{
if( mDump )
{
llinfos << tabs() << "endElement " << name << llendl;
}
if( !mCurrent->mContents.empty() )
{
LLStringUtil::trim(mCurrent->mContents);
LLStringUtil::removeCRLF(mCurrent->mContents);
}
mCurrent = mCurrent->getParent();
}
void LLXmlTreeParser::characterData(const char *s, int len)
{
std::string str;
if (s) str = std::string(s, len);
if( mDump )
{
llinfos << tabs() << "CharacterData " << str << llendl;
}
if (mKeepContents)
{
mCurrent->appendContents( str );
}
}
void LLXmlTreeParser::processingInstruction(const char *target, const char *data)
{
if( mDump )
{
llinfos << tabs() << "processingInstruction " << data << llendl;
}
}
void LLXmlTreeParser::comment(const char *data)
{
if( mDump )
{
llinfos << tabs() << "comment " << data << llendl;
}
}
void LLXmlTreeParser::startCdataSection()
{
if( mDump )
{
llinfos << tabs() << "startCdataSection" << llendl;
}
}
void LLXmlTreeParser::endCdataSection()
{
if( mDump )
{
llinfos << tabs() << "endCdataSection" << llendl;
}
}
void LLXmlTreeParser::defaultData(const char *s, int len)
{
if( mDump )
{
std::string str;
if (s) str = std::string(s, len);
llinfos << tabs() << "defaultData " << str << llendl;
}
}
void LLXmlTreeParser::unparsedEntityDecl(
const char* entity_name,
const char* base,
const char* system_id,
const char* public_id,
const char* notation_name)
{
if( mDump )
{
llinfos << tabs() << "unparsed entity:" << llendl;
llinfos << tabs() << " entityName " << entity_name << llendl;
llinfos << tabs() << " base " << base << llendl;
llinfos << tabs() << " systemId " << system_id << llendl;
llinfos << tabs() << " publicId " << public_id << llendl;
llinfos << tabs() << " notationName " << notation_name<< llendl;
}
}
void test_llxmltree()
{
LLXmlTree tree;
BOOL success = tree.parseFile( "test.xml" );
if( success )
{
tree.dump();
}
}

240
indra/llxml/llxmltree.h Normal file
View File

@@ -0,0 +1,240 @@
/**
* @file llxmltree.h
* @author Aaron Yonas, Richard Nelson
* @brief LLXmlTree class definition
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLXMLTREE_H
#define LL_LLXMLTREE_H
#include <map>
#include <list>
#include "llstring.h"
#include "llxmlparser.h"
#include "string_table.h"
class LLColor4;
class LLColor4U;
class LLQuaternion;
class LLUUID;
class LLVector3;
class LLVector3d;
class LLXmlTreeNode;
class LLXmlTreeParser;
//////////////////////////////////////////////////////////////
// LLXmlTree
class LLXmlTree
{
friend class LLXmlTreeNode;
public:
LLXmlTree();
virtual ~LLXmlTree();
void cleanup();
virtual BOOL parseFile(const std::string &path, BOOL keep_contents = TRUE);
LLXmlTreeNode* getRoot() { return mRoot; }
void dump();
void dumpNode( LLXmlTreeNode* node, const std::string& prefix );
static LLStdStringHandle addAttributeString( const std::string& name)
{
return sAttributeKeys.addString( name );
}
public:
// global
static LLStdStringTable sAttributeKeys;
protected:
LLXmlTreeNode* mRoot;
// local
LLStdStringTable mNodeNames;
};
//////////////////////////////////////////////////////////////
// LLXmlTreeNode
class LLXmlTreeNode
{
friend class LLXmlTree;
friend class LLXmlTreeParser;
protected:
// Protected since nodes are only created and destroyed by friend classes and other LLXmlTreeNodes
LLXmlTreeNode( const std::string& name, LLXmlTreeNode* parent, LLXmlTree* tree );
public:
virtual ~LLXmlTreeNode();
const std::string& getName()
{
return mName;
}
BOOL hasName( const std::string& name )
{
return mName == name;
}
BOOL hasAttribute( const std::string& name );
// Fast versions use cannonical_name handlee to entru in LLXmlTree::sAttributeKeys string table
BOOL getFastAttributeBOOL( LLStdStringHandle cannonical_name, BOOL& value );
BOOL getFastAttributeU8( LLStdStringHandle cannonical_name, U8& value );
BOOL getFastAttributeS8( LLStdStringHandle cannonical_name, S8& value );
BOOL getFastAttributeU16( LLStdStringHandle cannonical_name, U16& value );
BOOL getFastAttributeS16( LLStdStringHandle cannonical_name, S16& value );
BOOL getFastAttributeU32( LLStdStringHandle cannonical_name, U32& value );
BOOL getFastAttributeS32( LLStdStringHandle cannonical_name, S32& value );
BOOL getFastAttributeF32( LLStdStringHandle cannonical_name, F32& value );
BOOL getFastAttributeF64( LLStdStringHandle cannonical_name, F64& value );
BOOL getFastAttributeColor( LLStdStringHandle cannonical_name, LLColor4& value );
BOOL getFastAttributeColor4( LLStdStringHandle cannonical_name, LLColor4& value );
BOOL getFastAttributeColor4U( LLStdStringHandle cannonical_name, LLColor4U& value );
BOOL getFastAttributeVector3( LLStdStringHandle cannonical_name, LLVector3& value );
BOOL getFastAttributeVector3d( LLStdStringHandle cannonical_name, LLVector3d& value );
BOOL getFastAttributeQuat( LLStdStringHandle cannonical_name, LLQuaternion& value );
BOOL getFastAttributeUUID( LLStdStringHandle cannonical_name, LLUUID& value );
BOOL getFastAttributeString( LLStdStringHandle cannonical_name, std::string& value );
// Normal versions find 'name' in LLXmlTree::sAttributeKeys then call fast versions
virtual BOOL getAttributeBOOL( const std::string& name, BOOL& value );
virtual BOOL getAttributeU8( const std::string& name, U8& value );
virtual BOOL getAttributeS8( const std::string& name, S8& value );
virtual BOOL getAttributeU16( const std::string& name, U16& value );
virtual BOOL getAttributeS16( const std::string& name, S16& value );
virtual BOOL getAttributeU32( const std::string& name, U32& value );
virtual BOOL getAttributeS32( const std::string& name, S32& value );
virtual BOOL getAttributeF32( const std::string& name, F32& value );
virtual BOOL getAttributeF64( const std::string& name, F64& value );
virtual BOOL getAttributeColor( const std::string& name, LLColor4& value );
virtual BOOL getAttributeColor4( const std::string& name, LLColor4& value );
virtual BOOL getAttributeColor4U( const std::string& name, LLColor4U& value );
virtual BOOL getAttributeVector3( const std::string& name, LLVector3& value );
virtual BOOL getAttributeVector3d( const std::string& name, LLVector3d& value );
virtual BOOL getAttributeQuat( const std::string& name, LLQuaternion& value );
virtual BOOL getAttributeUUID( const std::string& name, LLUUID& value );
virtual BOOL getAttributeString( const std::string& name, std::string& value );
const std::string& getContents()
{
return mContents;
}
std::string getTextContents();
LLXmlTreeNode* getParent() { return mParent; }
LLXmlTreeNode* getFirstChild();
LLXmlTreeNode* getNextChild();
S32 getChildCount() { return (S32)mChildList.size(); }
LLXmlTreeNode* getChildByName( const std::string& name ); // returns first child with name, NULL if none
LLXmlTreeNode* getNextNamedChild(); // returns next child with name, NULL if none
protected:
const std::string* getAttribute( LLStdStringHandle name)
{
attribute_map_t::iterator iter = mAttributes.find(name);
return (iter == mAttributes.end()) ? 0 : iter->second;
}
private:
void addAttribute( const std::string& name, const std::string& value );
void appendContents( const std::string& str );
void addChild( LLXmlTreeNode* child );
void dump( const std::string& prefix );
protected:
typedef std::map<LLStdStringHandle, const std::string*> attribute_map_t;
attribute_map_t mAttributes;
private:
std::string mName;
std::string mContents;
typedef std::list<class LLXmlTreeNode *> child_list_t;
child_list_t mChildList;
child_list_t::iterator mChildListIter;
typedef std::multimap<LLStdStringHandle, LLXmlTreeNode *> child_map_t;
child_map_t mChildMap; // for fast name lookups
child_map_t::iterator mChildMapIter;
child_map_t::iterator mChildMapEndIter;
LLXmlTreeNode* mParent;
LLXmlTree* mTree;
};
//////////////////////////////////////////////////////////////
// LLXmlTreeParser
class LLXmlTreeParser : public LLXmlParser
{
public:
LLXmlTreeParser(LLXmlTree* tree);
virtual ~LLXmlTreeParser();
BOOL parseFile(const std::string &path, LLXmlTreeNode** root, BOOL keep_contents );
protected:
const std::string& tabs();
// Overrides from LLXmlParser
virtual void startElement(const char *name, const char **attributes);
virtual void endElement(const char *name);
virtual void characterData(const char *s, int len);
virtual void processingInstruction(const char *target, const char *data);
virtual void comment(const char *data);
virtual void startCdataSection();
virtual void endCdataSection();
virtual void defaultData(const char *s, int len);
virtual void unparsedEntityDecl(
const char* entity_name,
const char* base,
const char* system_id,
const char* public_id,
const char* notation_name);
//template method pattern
virtual LLXmlTreeNode* CreateXmlTreeNode(const std::string& name, LLXmlTreeNode* parent);
protected:
LLXmlTree* mTree;
LLXmlTreeNode* mRoot;
LLXmlTreeNode* mCurrent;
BOOL mDump; // Dump parse tree to llinfos as it is read.
BOOL mKeepContents;
};
#endif // LL_LLXMLTREE_H