summaryrefslogtreecommitdiff
path: root/indra/llxuixml/llinitparam.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llxuixml/llinitparam.h')
-rw-r--r--indra/llxuixml/llinitparam.h204
1 files changed, 116 insertions, 88 deletions
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index b645c4be7c..8cb5bd80fc 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -3,31 +3,25 @@ f * @file llinitparam.h
* @brief parameter block abstraction for creating complex objects and
* parsing construction parameters from xml and LLSD
*
- * $LicenseInfo:firstyear=2008&license=viewergpl$
- *
- * Copyright (c) 2008-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2008&license=viewerlgpl$
* 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
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * 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
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * 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.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -40,6 +34,7 @@ f * @file llinitparam.h
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/type_traits/is_convertible.hpp>
+#include <boost/unordered_map.hpp>
#include "llregistry.h"
#include "llmemory.h"
@@ -202,36 +197,39 @@ namespace LLInitParam
typedef std::pair<name_stack_t::const_iterator, name_stack_t::const_iterator> name_stack_range_t;
typedef std::vector<std::string> possible_values_t;
- typedef boost::function<bool (void*)> parser_read_func_t;
- typedef boost::function<bool (const void*, const name_stack_t&)> parser_write_func_t;
+ typedef bool (*parser_read_func_t)(Parser& parser, void* output);
+ typedef bool (*parser_write_func_t)(Parser& parser, const void*, const name_stack_t&);
typedef boost::function<void (const name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t;
typedef std::map<const std::type_info*, parser_read_func_t, CompareTypeID> parser_read_func_map_t;
typedef std::map<const std::type_info*, parser_write_func_t, CompareTypeID> parser_write_func_map_t;
typedef std::map<const std::type_info*, parser_inspect_func_t, CompareTypeID> parser_inspect_func_map_t;
- Parser()
+ Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
: mParseSilently(false),
- mParseGeneration(0)
+ mParseGeneration(0),
+ mParserReadFuncs(&read_map),
+ mParserWriteFuncs(&write_map),
+ mParserInspectFuncs(&inspect_map)
{}
virtual ~Parser();
template <typename T> bool readValue(T& param)
{
- parser_read_func_map_t::iterator found_it = mParserReadFuncs.find(&typeid(T));
- if (found_it != mParserReadFuncs.end())
+ parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
+ if (found_it != mParserReadFuncs->end())
{
- return found_it->second((void*)&param);
+ return found_it->second(*this, (void*)&param);
}
return false;
}
template <typename T> bool writeValue(const T& param, const name_stack_t& name_stack)
{
- parser_write_func_map_t::iterator found_it = mParserWriteFuncs.find(&typeid(T));
- if (found_it != mParserWriteFuncs.end())
+ parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T));
+ if (found_it != mParserWriteFuncs->end())
{
- return found_it->second((const void*)&param, name_stack);
+ return found_it->second(*this, (const void*)&param, name_stack);
}
return false;
}
@@ -239,8 +237,8 @@ namespace LLInitParam
// dispatch inspection to registered inspection functions, for each parameter in a param block
template <typename T> bool inspectValue(const name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values)
{
- parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs.find(&typeid(T));
- if (found_it != mParserInspectFuncs.end())
+ parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs->find(&typeid(T));
+ if (found_it != mParserInspectFuncs->end())
{
found_it->second(name_stack, min_count, max_count, possible_values);
return true;
@@ -252,7 +250,6 @@ namespace LLInitParam
virtual void parserWarning(const std::string& message);
virtual void parserError(const std::string& message);
void setParseSilently(bool silent) { mParseSilently = silent; }
- bool getParseSilently() { return mParseSilently; }
S32 getParseGeneration() { return mParseGeneration; }
S32 newParseGeneration() { return ++mParseGeneration; }
@@ -260,24 +257,24 @@ namespace LLInitParam
protected:
template <typename T>
- void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func)
+ void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func = NULL)
{
- mParserReadFuncs.insert(std::make_pair(&typeid(T), read_func));
- mParserWriteFuncs.insert(std::make_pair(&typeid(T), write_func));
+ mParserReadFuncs->insert(std::make_pair(&typeid(T), read_func));
+ mParserWriteFuncs->insert(std::make_pair(&typeid(T), write_func));
}
template <typename T>
void registerInspectFunc(parser_inspect_func_t inspect_func)
{
- mParserInspectFuncs.insert(std::make_pair(&typeid(T), inspect_func));
+ mParserInspectFuncs->insert(std::make_pair(&typeid(T), inspect_func));
}
bool mParseSilently;
private:
- parser_read_func_map_t mParserReadFuncs;
- parser_write_func_map_t mParserWriteFuncs;
- parser_inspect_func_map_t mParserInspectFuncs;
+ parser_read_func_map_t* mParserReadFuncs;
+ parser_write_func_map_t* mParserWriteFuncs;
+ parser_inspect_func_map_t* mParserInspectFuncs;
S32 mParseGeneration;
};
@@ -290,7 +287,7 @@ namespace LLInitParam
void setProvided(bool is_provided) { mIsProvided = is_provided; }
protected:
- bool getProvided() const { return mIsProvided; }
+ bool anyProvided() const { return mIsProvided; }
Param(class BaseBlock* enclosing_block);
@@ -386,14 +383,13 @@ namespace LLInitParam
void aggregateBlockData(BlockDescriptor& src_block_data);
public:
- typedef std::map<const std::string, ParamDescriptor*> param_map_t; // references param descriptors stored in mAllParams
+ typedef boost::unordered_map<const std::string, ParamDescriptor*> param_map_t; // references param descriptors stored in mAllParams
typedef std::vector<ParamDescriptor*> param_list_t;
typedef std::list<ParamDescriptor> all_params_list_t;// references param descriptors stored in mAllParams
typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> > param_validation_list_t;
param_map_t mNamedParams; // parameters with associated names
- param_map_t mSynonyms; // parameters with alternate names
param_list_t mUnnamedParams; // parameters with_out_ associated names
param_validation_list_t mValidationList; // parameters that must be validated
all_params_list_t mAllParams; // all parameters, owns descriptors
@@ -479,8 +475,8 @@ namespace LLInitParam
bool serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const;
bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t()) const;
- const BlockDescriptor& mostDerivedBlockDescriptor() const { return *mBlockDescriptor; }
- BlockDescriptor& mostDerivedBlockDescriptor() { return *mBlockDescriptor; }
+ virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
+ virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
// take all provided params from other and apply to self
bool overwriteFrom(const BaseBlock& other)
@@ -505,8 +501,6 @@ namespace LLInitParam
// can be updated in getters
mutable S32 mChangeVersion;
- BlockDescriptor* mBlockDescriptor; // most derived block descriptor
-
static BlockDescriptor& selfBlockDescriptor()
{
static BlockDescriptor sBlockDescriptor;
@@ -574,7 +568,7 @@ namespace LLInitParam
mData.mValue = value;
}
- bool isProvided() const { return Param::getProvided(); }
+ bool isProvided() const { return Param::anyProvided(); }
static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
{
@@ -582,7 +576,7 @@ namespace LLInitParam
// no further names in stack, attempt to parse value now
if (name_stack.first == name_stack.second)
{
- if (parser.readValue<T>(typed_param.mData.mValue))
+ if (parser.readValue(typed_param.mData.mValue))
{
typed_param.mData.clearKey();
typed_param.setProvided(true);
@@ -595,7 +589,7 @@ namespace LLInitParam
{
// try to parse a known named value
std::string name;
- if (parser.readValue<std::string>(name))
+ if (parser.readValue(name))
{
// try to parse a per type named value
if (NAME_VALUE_LOOKUP::get(name, typed_param.mData.mValue))
@@ -630,7 +624,7 @@ namespace LLInitParam
{
if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key))
{
- if (!parser.writeValue<std::string>(key, name_stack))
+ if (!parser.writeValue(key, name_stack))
{
return;
}
@@ -638,7 +632,7 @@ namespace LLInitParam
}
// then try to serialize value directly
else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), static_cast<const self_t*>(diff_param)->get())) {
- if (!parser.writeValue<T>(typed_param.mData.mValue, name_stack))
+ if (!parser.writeValue(typed_param.mData.mValue, name_stack))
{
return;
}
@@ -751,7 +745,7 @@ namespace LLInitParam
{
// try to parse a known named value
std::string name;
- if (parser.readValue<std::string>(name))
+ if (parser.readValue(name))
{
// try to parse a per type named value
if (NAME_VALUE_LOOKUP::get(name, typed_param))
@@ -778,7 +772,7 @@ namespace LLInitParam
std::string key = typed_param.mData.getKey();
if (!key.empty() && typed_param.mData.mKeyVersion == typed_param.getLastChangeVersion())
{
- if (!parser.writeValue<std::string>(key, name_stack))
+ if (!parser.writeValue(key, name_stack))
{
return;
}
@@ -801,13 +795,13 @@ namespace LLInitParam
bool isProvided() const
{
// only validate block when it hasn't already passed validation and user has supplied *some* value
- if (Param::getProvided() && mData.mValidatedVersion < T::getLastChangeVersion())
+ if (Param::anyProvided() && mData.mValidatedVersion < T::getLastChangeVersion())
{
// a sub-block is "provided" when it has been filled in enough to be valid
mData.mValidated = T::validateBlock(false);
mData.mValidatedVersion = T::getLastChangeVersion();
}
- return Param::getProvided() && mData.mValidated;
+ return Param::anyProvided() && mData.mValidated;
}
// assign block contents to this param-that-is-a-block
@@ -858,7 +852,7 @@ namespace LLInitParam
{
const self_t& src_typed_param = static_cast<const self_t&>(src);
self_t& dst_typed_param = static_cast<self_t&>(dst);
- if (dst_typed_param.T::merge(T::selfBlockDescriptor(), src_typed_param, overwrite || !dst_typed_param.isProvided()))
+ if (dst_typed_param.T::merge(T::selfBlockDescriptor(), src_typed_param, overwrite))
{
dst_typed_param.mData.clearKey();
return true;
@@ -915,7 +909,7 @@ namespace LLInitParam
}
}
- bool isProvided() const { return Param::getProvided(); }
+ bool isProvided() const { return Param::anyProvided(); }
static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
{
@@ -925,7 +919,7 @@ namespace LLInitParam
if (name_stack.first == name_stack.second)
{
// attempt to read value directly
- if (parser.readValue<value_t>(value))
+ if (parser.readValue(value))
{
typed_param.mValues.push_back(value);
// save an empty name/value key as a placeholder
@@ -940,7 +934,7 @@ namespace LLInitParam
{
// try to parse a known named value
std::string name;
- if (parser.readValue<std::string>(name))
+ if (parser.readValue(name))
{
// try to parse a per type named value
if (NAME_VALUE_LOOKUP::get(name, typed_param.mValues))
@@ -964,7 +958,7 @@ namespace LLInitParam
const self_t& typed_param = static_cast<const self_t&>(param);
if (!typed_param.isProvided() || name_stack.empty()) return;
- typename container_t::const_iterator it = typed_param.mValues.begin();
+ const_iterator it = typed_param.mValues.begin();
for (typename std::vector<key_cache_t>::const_iterator key_it = typed_param.mCachedKeys.begin();
it != typed_param.mValues.end();
++key_it, ++it)
@@ -974,13 +968,13 @@ namespace LLInitParam
if(!key.empty())
{
- if(!parser.writeValue<std::string>(key, name_stack))
+ if(!parser.writeValue(key, name_stack))
{
return;
}
}
// not parse via name values, write out value directly
- else if (!parser.writeValue<VALUE_TYPE>(*it, name_stack))
+ else if (!parser.writeValue(*it, name_stack))
{
return;
}
@@ -1031,8 +1025,15 @@ namespace LLInitParam
// implicit conversion
operator value_assignment_t() const { return self_t::get(); }
- // explicit conversion
- value_assignment_t operator()() const { return get(); }
+
+ typedef typename container_t::iterator iterator;
+ typedef typename container_t::const_iterator const_iterator;
+ iterator begin() { return mValues.begin(); }
+ iterator end() { return mValues.end(); }
+ const_iterator begin() const { return mValues.begin(); }
+ const_iterator end() const { return mValues.end(); }
+ bool empty() const { return mValues.empty(); }
+ size_t size() const { return mValues.size(); }
U32 numValidElements() const
{
@@ -1098,7 +1099,7 @@ namespace LLInitParam
}
}
- bool isProvided() const { return Param::getProvided(); }
+ bool isProvided() const { return Param::anyProvided(); }
value_ref_t operator[](S32 index) { return mValues[index]; }
value_const_ref_t operator[](S32 index) const { return mValues[index]; }
@@ -1106,32 +1107,41 @@ namespace LLInitParam
static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
{
self_t& typed_param = static_cast<self_t&>(param);
+ bool new_value = false;
if (generation != typed_param.mLastParamGeneration || typed_param.mValues.empty())
{
+ new_value = true;
typed_param.mValues.push_back(value_t());
typed_param.mCachedKeys.push_back(Data());
- typed_param.enclosingBlock().setLastChangedParam(param, true);
- typed_param.mLastParamGeneration = generation;
}
- value_t& value = typed_param.mValues.back();
+ value_ref_t value = typed_param.mValues.back();
// attempt to parse block...
if(value.deserializeBlock(parser, name_stack))
{
+ if (new_value)
+ { // successfully parsed new value, let's keep it
+ typed_param.mLastParamGeneration = generation;
+ }
+ typed_param.enclosingBlock().setLastChangedParam(param, true);
typed_param.setProvided(true);
return true;
}
-
- if(!NAME_VALUE_LOOKUP::empty())
+ else if(!NAME_VALUE_LOOKUP::empty())
{
// try to parse a known named value
std::string name;
- if (parser.readValue<std::string>(name))
+ if (parser.readValue(name))
{
// try to parse a per type named value
if (NAME_VALUE_LOOKUP::get(name, value))
{
+ if (new_value)
+ { // successfully parsed new value, let's keep it
+ typed_param.mLastParamGeneration = generation;
+ }
+
typed_param.mCachedKeys.back().setKey(name);
typed_param.mCachedKeys.back().mKeyVersion = value.getLastChangeVersion();
typed_param.enclosingBlock().setLastChangedParam(param, true);
@@ -1142,6 +1152,12 @@ namespace LLInitParam
}
}
+ if (new_value)
+ { // failed to parse new value, pop it off
+ typed_param.mValues.pop_back();
+ typed_param.mCachedKeys.pop_back();
+ }
+
return false;
}
@@ -1150,7 +1166,7 @@ namespace LLInitParam
const self_t& typed_param = static_cast<const self_t&>(param);
if (!typed_param.isProvided() || name_stack.empty()) return;
- typename container_t::const_iterator it = typed_param.mValues.begin();
+ const_iterator it = typed_param.mValues.begin();
for (typename std::vector<Data>::const_iterator key_it = typed_param.mCachedKeys.begin();
it != typed_param.mValues.end();
++key_it, ++it)
@@ -1160,7 +1176,7 @@ namespace LLInitParam
std::string key = key_it->getKey();
if (!key.empty() && key_it->mKeyVersion == it->getLastChangeVersion())
{
- if(!parser.writeValue<std::string>(key, name_stack))
+ if(!parser.writeValue(key, name_stack))
{
return;
}
@@ -1214,13 +1230,20 @@ namespace LLInitParam
// implicit conversion
operator value_assignment_t() const { return self_t::get(); }
- // explicit conversion
- value_assignment_t operator()() const { return get(); }
+
+ typedef typename container_t::iterator iterator;
+ typedef typename container_t::const_iterator const_iterator;
+ iterator begin() { return mValues.begin(); }
+ iterator end() { return mValues.end(); }
+ const_iterator begin() const { return mValues.begin(); }
+ const_iterator end() const { return mValues.end(); }
+ bool empty() const { return mValues.empty(); }
+ size_t size() const { return mValues.size(); }
U32 numValidElements() const
{
U32 count = 0;
- for (typename container_t::const_iterator it = mValues.begin();
+ for (const_iterator it = mValues.begin();
it != mValues.end();
++it)
{
@@ -1312,6 +1335,9 @@ namespace LLInitParam
BaseBlock::setLastChangedParam(last_param, user_provided);
}
+ virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
+ virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+
protected:
Choice()
: mCurChoice(0)
@@ -1421,6 +1447,10 @@ namespace LLInitParam
{
return BaseBlock::merge(selfBlockDescriptor(), other, false);
}
+
+ virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
+ virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+
protected:
Block()
{
@@ -1500,15 +1530,13 @@ namespace LLInitParam
typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP> self_t;
typedef typename super_t::container_t container_t;
typedef typename super_t::value_assignment_t value_assignment_t;
- typedef typename container_t::iterator iterator;
- typedef typename container_t::const_iterator const_iterator;
+ typedef typename super_t::iterator iterator;
+ typedef typename super_t::const_iterator const_iterator;
explicit Multiple(const char* name = "", value_assignment_t val = DefaultInitializer<container_t>::get())
: super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, RANGE::minCount(), RANGE::maxCount())
{}
- using super_t::operator();
-
Multiple& operator=(value_assignment_t val)
{
set(val);
@@ -1618,7 +1646,7 @@ namespace LLInitParam
// type to apply parse direct value T
if (name_stack.first == name_stack.second)
{
- if(parser.readValue<T>(typed_param.mData.mValue))
+ if(parser.readValue(typed_param.mData.mValue))
{
typed_param.enclosingBlock().setLastChangedParam(param, true);
typed_param.setProvided(true);
@@ -1633,7 +1661,7 @@ namespace LLInitParam
{
// try to parse a known named value
std::string name;
- if (parser.readValue<std::string>(name))
+ if (parser.readValue(name))
{
// try to parse a per type named value
if (TypeValues<T>::get(name, typed_param.mData.mValue))
@@ -1675,7 +1703,7 @@ namespace LLInitParam
{
if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key))
{
- if (!parser.writeValue<std::string>(key, name_stack))
+ if (!parser.writeValue(key, name_stack))
{
return;
}
@@ -1685,7 +1713,7 @@ namespace LLInitParam
else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), (static_cast<const self_t*>(diff_param))->get()))
{
- if (parser.writeValue<T>(typed_param.mData.mValue, name_stack))
+ if (parser.writeValue(typed_param.mData.mValue, name_stack))
{
return;
}
@@ -1718,7 +1746,7 @@ namespace LLInitParam
bool isProvided() const
{
- if (!Param::getProvided()) return false;
+ if (!Param::anyProvided()) return false;
// block has an updated parameter
// if cached value is stale, regenerate from params
@@ -1785,7 +1813,7 @@ namespace LLInitParam
value_assignment_t get() const
{
// if some parameters were provided, issue warnings on invalid blocks
- if (Param::getProvided() && (mData.mValueAge == OLDER_THAN_BLOCK))
+ if (Param::anyProvided() && (mData.mValueAge == OLDER_THAN_BLOCK))
{
// go ahead and issue warnings at this point if any param is invalid
if(block_t::validateBlock(true))