Imported existing code
This commit is contained in:
43
indra/llxml/CMakeLists.txt
Normal file
43
indra/llxml/CMakeLists.txt
Normal 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
1271
indra/llxml/llcontrol.cpp
Normal file
File diff suppressed because it is too large
Load Diff
245
indra/llxml/llcontrol.h
Normal file
245
indra/llxml/llcontrol.h
Normal 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
|
||||
74
indra/llxml/llcontrolgroupreader.h
Normal file
74
indra/llxml/llcontrolgroupreader.h
Normal 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
3217
indra/llxml/llxmlnode.cpp
Normal file
File diff suppressed because it is too large
Load Diff
327
indra/llxml/llxmlnode.h
Normal file
327
indra/llxml/llxmlnode.h
Normal 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
422
indra/llxml/llxmlparser.cpp
Normal 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
139
indra/llxml/llxmlparser.h
Normal 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
697
indra/llxml/llxmltree.cpp
Normal 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
240
indra/llxml/llxmltree.h
Normal 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
|
||||
Reference in New Issue
Block a user