summaryrefslogtreecommitdiff
path: root/indra/llxuixml/llinitparam.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llxuixml/llinitparam.cpp')
-rw-r--r--indra/llxuixml/llinitparam.cpp222
1 files changed, 114 insertions, 108 deletions
diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
index 2ead5a4a57..b3312798dd 100644
--- a/indra/llxuixml/llinitparam.cpp
+++ b/indra/llxuixml/llinitparam.cpp
@@ -3,31 +3,25 @@
* @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.
*
- * 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 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.
*
- * 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.
+ * 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.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * 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
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -50,8 +44,51 @@ namespace LLInitParam
}
//
+ // ParamDescriptor
+ //
+ ParamDescriptor::ParamDescriptor(param_handle_t p,
+ merge_func_t merge_func,
+ deserialize_func_t deserialize_func,
+ serialize_func_t serialize_func,
+ validation_func_t validation_func,
+ inspect_func_t inspect_func,
+ S32 min_count,
+ S32 max_count)
+ : mParamHandle(p),
+ mMergeFunc(merge_func),
+ mDeserializeFunc(deserialize_func),
+ mSerializeFunc(serialize_func),
+ mValidationFunc(validation_func),
+ mInspectFunc(inspect_func),
+ mMinCount(min_count),
+ mMaxCount(max_count),
+ mGeneration(0),
+ mUserData(NULL)
+ {}
+
+ ParamDescriptor::ParamDescriptor()
+ : mParamHandle(0),
+ mMergeFunc(NULL),
+ mDeserializeFunc(NULL),
+ mSerializeFunc(NULL),
+ mValidationFunc(NULL),
+ mInspectFunc(NULL),
+ mMinCount(0),
+ mMaxCount(0),
+ mGeneration(0),
+ mUserData(NULL)
+ {}
+
+ ParamDescriptor::~ParamDescriptor()
+ {
+ delete mUserData;
+ }
+
+ //
// Parser
//
+ S32 Parser::sNextParseGeneration = 0;
+
Parser::~Parser()
{}
@@ -74,18 +111,22 @@ namespace LLInitParam
void BlockDescriptor::aggregateBlockData(BlockDescriptor& src_block_data)
{
mNamedParams.insert(src_block_data.mNamedParams.begin(), src_block_data.mNamedParams.end());
- mSynonyms.insert(src_block_data.mSynonyms.begin(), src_block_data.mSynonyms.end());
std::copy(src_block_data.mUnnamedParams.begin(), src_block_data.mUnnamedParams.end(), std::back_inserter(mUnnamedParams));
std::copy(src_block_data.mValidationList.begin(), src_block_data.mValidationList.end(), std::back_inserter(mValidationList));
std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));
}
+ BlockDescriptor::BlockDescriptor()
+ : mMaxParamOffset(0),
+ mInitializationState(UNINITIALIZED),
+ mCurrentBlockPtr(NULL)
+ {}
+
//
// BaseBlock
//
BaseBlock::BaseBlock()
- : mChangeVersion(0),
- mBlockDescriptor(NULL)
+ : mChangeVersion(0)
{}
BaseBlock::~BaseBlock()
@@ -94,8 +135,6 @@ namespace LLInitParam
// called by each derived class in least to most derived order
void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)
{
- mBlockDescriptor = &descriptor;
-
descriptor.mCurrentBlockPtr = this;
descriptor.mMaxParamOffset = block_size;
@@ -125,7 +164,7 @@ namespace LLInitParam
bool BaseBlock::submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent)
{
- if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end())))
+ if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()), -1))
{
if (!silent)
{
@@ -139,7 +178,7 @@ namespace LLInitParam
bool BaseBlock::validateBlock(bool emit_errors) const
{
- const BlockDescriptor& block_data = getBlockDescriptor();
+ const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
for (BlockDescriptor::param_validation_list_t::const_iterator it = block_data.mValidationList.begin(); it != block_data.mValidationList.end(); ++it)
{
const Param* param = getParamFromHandle(it->first);
@@ -155,11 +194,11 @@ namespace LLInitParam
return true;
}
- bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const
+ void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const
{
// named param is one like LLView::Params::follows
// unnamed param is like LLView::Params::rect - implicit
- const BlockDescriptor& block_data = getBlockDescriptor();
+ const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin();
it != block_data.mUnnamedParams.end();
@@ -188,7 +227,7 @@ namespace LLInitParam
param_handle_t param_handle = it->second->mParamHandle;
const Param* param = getParamFromHandle(param_handle);
ParamDescriptor::serialize_func_t serialize_func = it->second->mSerializeFunc;
- if (serialize_func)
+ if (serialize_func && param->anyProvided())
{
// Ensure this param has not already been serialized
// Prevents <rect> from being serialized as its own tag.
@@ -222,15 +261,13 @@ namespace LLInitParam
name_stack.pop_back();
}
}
-
- return true;
}
- bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const
+ bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const
{
// named param is one like LLView::Params::follows
// unnamed param is like LLView::Params::rect - implicit
- const BlockDescriptor& block_data = getBlockDescriptor();
+ const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin();
it != block_data.mUnnamedParams.end();
@@ -280,30 +317,16 @@ namespace LLInitParam
}
}
- for(BlockDescriptor::param_map_t::const_iterator it = block_data.mSynonyms.begin();
- it != block_data.mSynonyms.end();
- ++it)
- {
- param_handle_t param_handle = it->second->mParamHandle;
- const Param* param = getParamFromHandle(param_handle);
- ParamDescriptor::inspect_func_t inspect_func = it->second->mInspectFunc;
- if (inspect_func)
- {
- // use existing serial number for param
- name_stack.push_back(std::make_pair(it->first, it->second->mGeneration));
- inspect_func(*param, parser, name_stack, it->second->mMinCount, it->second->mMaxCount);
- name_stack.pop_back();
- }
- }
-
return true;
}
- bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack)
+ bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 parent_generation)
{
- BlockDescriptor& block_data = getBlockDescriptor();
+ BlockDescriptor& block_data = mostDerivedBlockDescriptor();
bool names_left = name_stack.first != name_stack.second;
+ S32 parse_generation = name_stack.first == name_stack.second ? -1 : name_stack.first->second;
+
if (names_left)
{
const std::string& top_name = name_stack.first->first;
@@ -317,23 +340,10 @@ namespace LLInitParam
// find pointer to member parameter from offset table
paramp = getParamFromHandle(found_it->second->mParamHandle);
deserialize_func = found_it->second->mDeserializeFunc;
- }
- else
- {
- BlockDescriptor::param_map_t::iterator found_it = block_data.mSynonyms.find(top_name);
- if (found_it != block_data.mSynonyms.end())
- {
- // find pointer to member parameter from offset table
- paramp = getParamFromHandle(found_it->second->mParamHandle);
- deserialize_func = found_it->second->mDeserializeFunc;
- }
- }
- Parser::name_stack_range_t new_name_stack(name_stack.first, name_stack.second);
- ++new_name_stack.first;
- if (deserialize_func)
- {
- return deserialize_func(*paramp, p, new_name_stack, name_stack.first == name_stack.second ? -1 : name_stack.first->second);
+ Parser::name_stack_range_t new_name_stack(name_stack.first, name_stack.second);
+ ++new_name_stack.first;
+ return deserialize_func(*paramp, p, new_name_stack, parse_generation);
}
}
@@ -345,48 +355,56 @@ namespace LLInitParam
Param* paramp = getParamFromHandle((*it)->mParamHandle);
ParamDescriptor::deserialize_func_t deserialize_func = (*it)->mDeserializeFunc;
- if (deserialize_func && deserialize_func(*paramp, p, name_stack, name_stack.first == name_stack.second ? -1 : name_stack.first->second))
+ if (deserialize_func && deserialize_func(*paramp, p, name_stack, parse_generation))
{
return true;
}
}
+ // if no match, and no names left on stack, this is just an existence assertion of this block
+ // verify by calling readValue with NoParamValue type, an inherently unparseable type
+ if (!names_left)
+ {
+ NoParamValue no_value;
+ return p.readValue(no_value);
+ }
+
return false;
}
//static
- void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name)
+ void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name)
{
- // create a copy of the paramdescriptor in allparams
+ // create a copy of the param descriptor in mAllParams
// so other data structures can store a pointer to it
block_data.mAllParams.push_back(in_param);
- ParamDescriptor& param(block_data.mAllParams.back());
+ ParamDescriptorPtr param(block_data.mAllParams.back());
std::string name(char_name);
- if ((size_t)param.mParamHandle > block_data.mMaxParamOffset)
+ if ((size_t)param->mParamHandle > block_data.mMaxParamOffset)
{
llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
}
if (name.empty())
{
- block_data.mUnnamedParams.push_back(&param);
+ block_data.mUnnamedParams.push_back(param);
}
else
{
// don't use insert, since we want to overwrite existing entries
- block_data.mNamedParams[name] = &param;
+ block_data.mNamedParams[name] = param;
}
- if (param.mValidationFunc)
+ if (param->mValidationFunc)
{
- block_data.mValidationList.push_back(std::make_pair(param.mParamHandle, param.mValidationFunc));
+ block_data.mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));
}
}
void BaseBlock::addSynonym(Param& param, const std::string& synonym)
{
- BlockDescriptor& block_data = getBlockDescriptor();
+ BlockDescriptor& block_data = mostDerivedBlockDescriptor();
if (block_data.mInitializationState == BlockDescriptor::INITIALIZING)
{
param_handle_t handle = getHandleFromParam(&param);
@@ -398,7 +416,7 @@ namespace LLInitParam
llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
}
- ParamDescriptor* param_descriptor = findParamDescriptor(handle);
+ ParamDescriptorPtr param_descriptor = findParamDescriptor(param);
if (param_descriptor)
{
if (synonym.empty())
@@ -407,18 +425,18 @@ namespace LLInitParam
}
else
{
- block_data.mSynonyms[synonym] = param_descriptor;
+ block_data.mNamedParams[synonym] = param_descriptor;
}
}
}
}
- void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided)
+ void BaseBlock::paramChanged(const Param& changed_param, bool user_provided)
{
if (user_provided)
{
- mChangeVersion++;
- }
+ mChangeVersion++;
+ }
}
const std::string& BaseBlock::getParamName(const BlockDescriptor& block_data, const Param* paramp) const
@@ -432,53 +450,41 @@ namespace LLInitParam
}
}
- for (BlockDescriptor::param_map_t::const_iterator it = block_data.mSynonyms.begin(); it != block_data.mSynonyms.end(); ++it)
- {
- if (it->second->mParamHandle == handle)
- {
- return it->first;
- }
- }
-
return LLStringUtil::null;
}
- ParamDescriptor* BaseBlock::findParamDescriptor(param_handle_t handle)
+ ParamDescriptorPtr BaseBlock::findParamDescriptor(const Param& param)
{
- BlockDescriptor& descriptor = getBlockDescriptor();
+ param_handle_t handle = getHandleFromParam(&param);
+ BlockDescriptor& descriptor = mostDerivedBlockDescriptor();
BlockDescriptor::all_params_list_t::iterator end_it = descriptor.mAllParams.end();
for (BlockDescriptor::all_params_list_t::iterator it = descriptor.mAllParams.begin();
it != end_it;
++it)
{
- if (it->mParamHandle == handle) return &(*it);
+ if ((*it)->mParamHandle == handle) return *it;
}
- return NULL;
+ return ParamDescriptorPtr();
}
// take all provided params from other and apply to self
// NOTE: this requires that "other" is of the same derived type as this
- bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
+ bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
{
- bool param_changed = false;
+ bool some_param_changed = false;
BlockDescriptor::all_params_list_t::const_iterator end_it = block_data.mAllParams.end();
for (BlockDescriptor::all_params_list_t::const_iterator it = block_data.mAllParams.begin();
it != end_it;
++it)
{
- const Param* other_paramp = other.getParamFromHandle(it->mParamHandle);
- ParamDescriptor::merge_func_t merge_func = it->mMergeFunc;
+ const Param* other_paramp = other.getParamFromHandle((*it)->mParamHandle);
+ ParamDescriptor::merge_func_t merge_func = (*it)->mMergeFunc;
if (merge_func)
{
- Param* paramp = getParamFromHandle(it->mParamHandle);
- param_changed |= merge_func(*paramp, *other_paramp, overwrite);
+ Param* paramp = getParamFromHandle((*it)->mParamHandle);
+ some_param_changed |= merge_func(*paramp, *other_paramp, overwrite);
}
}
- return param_changed;
- }
-
- bool ParamCompare<LLSD, false>::equals(const LLSD &a, const LLSD &b)
- {
- return false;
+ return some_param_changed;
}
}