summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Linden <none@none>2011-11-08 13:48:38 -0800
committerRichard Linden <none@none>2011-11-08 13:48:38 -0800
commit7e6e3d20f334547d8cea78e8e0b37106efebe028 (patch)
tree92869b7a8b8dede9e79562eec0f235338db6f9b2
parentb6858df0dd9fa06ec8fa56c5ba63925a790b4811 (diff)
added Lazy modifier to params to support recursion
ChoiceBlock can now derive from another param block Params with name/value support can be assigned directly in C++ code using param = "named_value"
-rw-r--r--indra/llxuixml/llinitparam.h426
-rw-r--r--indra/llxuixml/llxuiparser.cpp258
2 files changed, 524 insertions, 160 deletions
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 183472450d..169a724bca 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -51,7 +51,7 @@ namespace LLInitParam
return a == b;
}
};
-
+
// boost function types are not comparable
template<typename T>
struct ParamCompare<T, true>
@@ -74,6 +74,7 @@ namespace LLInitParam
static bool equals(const Flag& a, const Flag& b) { return false; }
};
+
// helper functions and classes
typedef ptrdiff_t param_handle_t;
@@ -82,8 +83,11 @@ namespace LLInitParam
template <typename T>
class TypeValues
{
+ private:
+ struct Inaccessable{};
public:
typedef std::map<std::string, T> value_name_map_t;
+ typedef Inaccessable name_t;
void setValueName(const std::string& key) {}
std::string getValueName() const { return ""; }
@@ -113,6 +117,7 @@ namespace LLInitParam
{
public:
typedef typename std::map<std::string, T> value_name_map_t;
+ typedef std::string name_t;
//TODO: cache key by index to save on param block size
void setValueName(const std::string& value_name)
@@ -293,36 +298,7 @@ namespace LLInitParam
parser_inspect_func_map_t* mParserInspectFuncs;
};
- class BaseBlock;
-
- class Param
- {
- public:
- // public to allow choice blocks to clear provided flag on stale choices
- void setProvided(bool is_provided) { mIsProvided = is_provided; }
-
- protected:
- bool anyProvided() const { return mIsProvided; }
-
- Param(BaseBlock* enclosing_block);
-
- // store pointer to enclosing block as offset to reduce space and allow for quick copying
- BaseBlock& enclosingBlock() const
- {
- const U8* my_addr = reinterpret_cast<const U8*>(this);
- // get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class
- return *const_cast<BaseBlock*>
- (reinterpret_cast<const BaseBlock*>
- (my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset));
- }
-
- private:
- friend class BaseBlock;
-
- U32 mEnclosingBlockOffset:31;
- U32 mIsProvided:1;
-
- };
+ class Param;
// various callbacks and constraints associated with an individual param
struct ParamDescriptor
@@ -390,12 +366,91 @@ namespace LLInitParam
all_params_list_t mAllParams; // all parameters, owns descriptors
size_t mMaxParamOffset;
EInitializationState mInitializationState; // whether or not static block data has been initialized
- BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
+ class BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
};
class BaseBlock
{
public:
+ //TODO: implement in terms of owned_ptr
+ template<typename T>
+ class Lazy
+ {
+ public:
+ Lazy()
+ : mPtr(NULL)
+ {}
+
+ ~Lazy()
+ {
+ delete mPtr;
+ }
+
+ Lazy(const Lazy& other)
+ {
+ if (other.mPtr)
+ {
+ mPtr = new T(*other.mPtr);
+ }
+ else
+ {
+ mPtr = NULL;
+ }
+ }
+
+ Lazy<T>& operator = (const Lazy<T>& other)
+ {
+ if (other.mPtr)
+ {
+ mPtr = new T(*other.mPtr);
+ }
+ else
+ {
+ mPtr = NULL;
+ }
+ return *this;
+ }
+
+ bool empty() const
+ {
+ return mPtr == NULL;
+ }
+
+ void set(const T& other)
+ {
+ delete mPtr;
+ mPtr = new T(other);
+ }
+
+ const T& get() const
+ {
+ return ensureInstance();
+ }
+
+ T& get()
+ {
+ return ensureInstance();
+ }
+
+ private:
+ // lazily allocate an instance of T
+ T* ensureInstance() const
+ {
+ if (mPtr == NULL)
+ {
+ mPtr = new T();
+ }
+ return mPtr;
+ }
+
+ private:
+ // if you get a compilation error with this, that means you are using a forward declared struct for T
+ // unfortunately, the type traits we rely on don't work with forward declared typed
+ //static const int dummy = sizeof(T);
+
+ mutable T* mPtr;
+ };
+
// "Multiple" constraint types, put here in root class to avoid ambiguity during use
struct AnyAmount
{
@@ -511,6 +566,44 @@ namespace LLInitParam
const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
};
+ template<typename T>
+ struct ParamCompare<BaseBlock::Lazy<T>, false >
+ {
+ static bool equals(const BaseBlock::Lazy<T>& a, const BaseBlock::Lazy<T>& b) { return !a.empty() || !b.empty(); }
+ };
+
+ class Param
+ {
+ public:
+ void setProvided(bool is_provided = true)
+ {
+ mIsProvided = is_provided;
+ enclosingBlock().paramChanged(*this, is_provided);
+ }
+ protected:
+
+ bool anyProvided() const { return mIsProvided; }
+
+ Param(BaseBlock* enclosing_block);
+
+ // store pointer to enclosing block as offset to reduce space and allow for quick copying
+ BaseBlock& enclosingBlock() const
+ {
+ const U8* my_addr = reinterpret_cast<const U8*>(this);
+ // get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class
+ return *const_cast<BaseBlock*>
+ (reinterpret_cast<const BaseBlock*>
+ (my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset));
+ }
+
+ private:
+ friend class BaseBlock;
+
+ U32 mEnclosingBlockOffset:31;
+ U32 mIsProvided:1;
+
+ };
+
// these templates allow us to distinguish between template parameters
// that derive from BaseBlock and those that don't
template<typename T, typename Void = void>
@@ -530,6 +623,7 @@ namespace LLInitParam
{
public:
typedef const T& value_assignment_t;
+ typedef ParamValue<T, NAME_VALUE_LOOKUP, VALUE_IS_BLOCK> self_t;
ParamValue(): mValue() {}
ParamValue(value_assignment_t other) : mValue(other) {}
@@ -559,6 +653,25 @@ namespace LLInitParam
return mValue;
}
+ void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name)
+ {
+ *this = name;
+ }
+
+ self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
+ {
+ if (NAME_VALUE_LOOKUP::getValueFromName(name, mValue))
+ {
+ setValueName(name);
+ }
+
+ return *this;
+ }
+
+ self_t& operator =(const self_t& other)
+ {
+ mValue = other.mValue;
+ }
private:
T mValue;
@@ -571,17 +684,16 @@ namespace LLInitParam
{
public:
typedef const T& value_assignment_t;
+ typedef ParamValue<T, NAME_VALUE_LOOKUP, true> self_t;
ParamValue()
: T(),
- mKeyVersion(0),
mValidatedVersion(-1),
mValidated(false)
{}
ParamValue(value_assignment_t other)
: T(other),
- mKeyVersion(0),
mValidatedVersion(-1),
mValidated(false)
{}
@@ -611,8 +723,25 @@ namespace LLInitParam
return *this;
}
- S32 mKeyVersion;
+ void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name)
+ {
+ *this = name;
+ }
+ self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
+ {
+ if (NAME_VALUE_LOOKUP::getValueFromName(name, mValue))
+ {
+ setValueName(name);
+ }
+
+ return *this;
+ }
+
+ self_t& operator =(const self_t& other)
+ {
+ *(static_cast<T*>(this)) = other;
+ }
protected:
mutable S32 mValidatedVersion;
mutable bool mValidated; // lazy validation flag
@@ -671,8 +800,7 @@ namespace LLInitParam
if (parser.readValue(typed_param.getValue()))
{
typed_param.clearValueName();
- typed_param.setProvided(true);
- typed_param.enclosingBlock().paramChanged(param, true);
+ typed_param.setProvided();
return true;
}
@@ -687,8 +815,7 @@ namespace LLInitParam
if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
{
typed_param.setValueName(name);
- typed_param.setProvided(true);
- typed_param.enclosingBlock().paramChanged(param, true);
+ typed_param.setProvided();
return true;
}
@@ -744,12 +871,22 @@ namespace LLInitParam
}
}
+ self_t& operator =(typename const name_value_lookup_t::name_t& name)
+ {
+ if (name_value_lookup_t::getValueFromName(name, getValue()))
+ {
+ setValueName(name);
+ setProvided();
+ }
+
+ return *this;
+ }
+
void set(value_assignment_t val, bool flag_as_provided = true)
{
setValue(val);
param_value_t::clearValueName();
setProvided(flag_as_provided);
- Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
protected:
@@ -808,8 +945,7 @@ namespace LLInitParam
if(typed_param.deserializeBlock(parser, name_stack_range, new_name))
{
typed_param.clearValueName();
- typed_param.enclosingBlock().paramChanged(param, true);
- typed_param.setProvided(true);
+ typed_param.setProvided();
return true;
}
@@ -822,10 +958,8 @@ namespace LLInitParam
// try to parse a per type named value
if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
{
- typed_param.enclosingBlock().paramChanged(param, true);
typed_param.setValueName(name);
- typed_param.setProvided(true);
- typed_param.mKeyVersion = typed_param.getLastChangeVersion();
+ typed_param.setProvided();
return true;
}
@@ -845,7 +979,7 @@ namespace LLInitParam
}
std::string key = typed_param.getValueName();
- if (!key.empty() && typed_param.mKeyVersion == typed_param.getLastChangeVersion())
+ if (!key.empty())
{
if (!parser.writeValue(key, name_stack))
{
@@ -888,19 +1022,33 @@ namespace LLInitParam
// next call to isProvided() will update provision status based on validity
param_value_t::mValidatedVersion = -1;
setProvided(flag_as_provided);
- Param::enclosingBlock().paramChanged(*this, flag_as_provided);
+ }
+
+ self_t& operator =(typename const name_value_lookup_t::name_t& name)
+ {
+ if (name_value_lookup_t::getValueFromName(name, getValue()))
+ {
+ setValueName(name);
+ setProvided();
+ }
+
+ return *this;
}
// propagate changed status up to enclosing block
/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
{
param_value_t::paramChanged(changed_param, user_provided);
- Param::enclosingBlock().paramChanged(*this, user_provided);
if (user_provided)
{
// a child param has been explicitly changed
// so *some* aspect of this block is now provided
- setProvided(true);
+ setProvided();
+ param_value_t::clearValueName();
+ }
+ else
+ {
+ Param::enclosingBlock().paramChanged(*this, user_provided);
}
}
@@ -917,7 +1065,6 @@ namespace LLInitParam
{
dst_typed_param.clearValueName();
dst_typed_param.setProvided(true);
- dst_typed_param.enclosingBlock().paramChanged(dst_typed_param, true);
return true;
}
}
@@ -1004,7 +1151,7 @@ namespace LLInitParam
it != end_it;
++it)
{
- std::string key = it->getValue();
+ std::string key = it->getValueName();
name_stack.back().second = true;
if(key.empty())
@@ -1013,7 +1160,7 @@ namespace LLInitParam
bool value_written = parser.writeValue(*it, name_stack);
if (!value_written)
{
- std::string calculated_key = it->calcValueName(key);
+ std::string calculated_key = it->calcValueName(it->getValue());
if (!parser.writeValue(calculated_key, name_stack))
{
break;
@@ -1043,22 +1190,31 @@ namespace LLInitParam
{
mValues = val;
setProvided(flag_as_provided);
- Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
- value_t& add()
+ param_value_t& add()
{
mValues.push_back(param_value_t(value_t()));
- setProvided(true);
- Param::enclosingBlock().paramChanged(*this, true);
+ Param::setProvided();
return mValues.back();
}
void add(const value_t& item)
{
mValues.push_back(param_value_t(item));
- setProvided(true);
- Param::enclosingBlock().paramChanged(*this, true);
+ setProvided();
+ }
+
+ void add(typename const name_value_lookup_t::name_t& name)
+ {
+ value_t value;
+
+ // try to parse a per type named value
+ if (name_value_lookup_t::getValueFromName(name, value))
+ {
+ add(value);
+ mValues.back().setValueName(name);
+ }
}
// implicit conversion
@@ -1099,8 +1255,7 @@ namespace LLInitParam
if (src_typed_param.begin() != src_typed_param.end())
{
- dst_typed_param.setProvided(true);
- dst_typed_param.enclosingBlock().paramChanged(dst_typed_param, true);
+ dst_typed_param.setProvided();
}
return true;
}
@@ -1116,7 +1271,7 @@ namespace LLInitParam
public:
typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true> self_t;
typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP> param_value_t;
- typedef typename std::vector<param_value_t> container_t;
+ typedef typename std::vector<param_value_t> container_t;
typedef const container_t& value_assignment_t;
typedef VALUE_TYPE value_t;
typedef NAME_VALUE_LOOKUP name_value_lookup_t;
@@ -1158,8 +1313,7 @@ namespace LLInitParam
// attempt to parse block...
if(value.deserializeBlock(parser, name_stack_range, new_name))
{
- typed_param.enclosingBlock().paramChanged(param, true);
- typed_param.setProvided(true);
+ typed_param.setProvided();
return true;
}
else if(name_value_lookup_t::valueNamesExist())
@@ -1172,9 +1326,7 @@ namespace LLInitParam
if (name_value_lookup_t::getValueFromName(name, value.getValue()))
{
typed_param.mValues.back().setValueName(name);
- typed_param.mValues.back().mKeyVersion = value.getLastChangeVersion();
- typed_param.enclosingBlock().paramChanged(param, true);
- typed_param.setProvided(true);
+ typed_param.setProvided();
return true;
}
@@ -1201,7 +1353,7 @@ namespace LLInitParam
name_stack.back().second = true;
std::string key = it->getValueName();
- if (!key.empty() && it->mKeyVersion == it->getLastChangeVersion())
+ if (!key.empty())
{
parser.writeValue(key, name_stack);
}
@@ -1224,22 +1376,31 @@ namespace LLInitParam
{
mValues = val;
setProvided(flag_as_provided);
- Param::enclosingBlock().paramChanged(*this, flag_as_provided);
}
- value_t& add()
+ param_value_t& add()
{
mValues.push_back(value_t());
- setProvided(true);
- Param::enclosingBlock().paramChanged(*this, true);
+ setProvided();
return mValues.back();
}
void add(const value_t& item)
{
mValues.push_back(item);
- setProvided(true);
- Param::enclosingBlock().paramChanged(*this, true);
+ setProvided();
+ }
+
+ void add(typename const name_value_lookup_t::name_t& name)
+ {
+ value_t value;
+
+ // try to parse a per type named value
+ if (name_value_lookup_t::getValueFromName(name, value))
+ {
+ add(value);
+ mValues.back().setValueName(name);
+ }
}
// implicit conversion
@@ -1288,8 +1449,7 @@ namespace LLInitParam
if (src_typed_param.begin() != src_typed_param.end())
{
- dst_typed_param.setProvided(true);
- dst_typed_param.enclosingBlock().paramChanged(dst_typed_param, true);
+ dst_typed_param.setProvided();
}
return true;
@@ -1298,24 +1458,25 @@ namespace LLInitParam
container_t mValues;
};
- template <typename DERIVED_BLOCK>
- class ChoiceBlock : public BaseBlock
+ template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
+ class ChoiceBlock : public BASE_BLOCK
{
- typedef ChoiceBlock<DERIVED_BLOCK> self_t;
- typedef ChoiceBlock<DERIVED_BLOCK> enclosing_block_t;
+ typedef ChoiceBlock<DERIVED_BLOCK, BASE_BLOCK> self_t;
+ typedef ChoiceBlock<DERIVED_BLOCK, BASE_BLOCK> enclosing_block_t;
+ typedef BASE_BLOCK base_block_t;
LOG_CLASS(self_t);
public:
// take all provided params from other and apply to self
bool overwriteFrom(const self_t& other)
{
- return mergeBlock(selfBlockDescriptor(), other, true);
+ return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true);
}
// take all provided params that are not already provided, and apply to self
bool fillFrom(const self_t& other)
{
- return mergeBlock(selfBlockDescriptor(), other, false);
+ return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false);
}
bool mergeBlockParam(bool source_provided, bool dest_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
@@ -1333,25 +1494,25 @@ namespace LLInitParam
bool mergeBlock(BlockDescriptor& block_data, const self_t& other, bool overwrite)
{
mCurChoice = other.mCurChoice;
- return BaseBlock::mergeBlock(selfBlockDescriptor(), other, overwrite);
+ return base_block_t::mergeBlock(selfBlockDescriptor(), other, overwrite);
}
// clear out old choice when param has changed
/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
{
- param_handle_t changed_param_handle = BaseBlock::getHandleFromParam(&changed_param);
+ param_handle_t changed_param_handle = base_block_t::getHandleFromParam(&changed_param);
// if we have a new choice...
if (changed_param_handle != mCurChoice)
{
// clear provided flag on previous choice
- Param* previous_choice = BaseBlock::getParamFromHandle(mCurChoice);
+ Param* previous_choice = base_block_t::getParamFromHandle(mCurChoice);
if (previous_choice)
{
previous_choice->setProvided(false);
}
mCurChoice = changed_param_handle;
}
- BaseBlock::paramChanged(changed_param, user_provided);
+ base_block_t::paramChanged(changed_param, user_provided);
}
virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
@@ -1361,7 +1522,7 @@ namespace LLInitParam
ChoiceBlock()
: mCurChoice(0)
{
- BaseBlock::init(selfBlockDescriptor(), BaseBlock::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
+ BaseBlock::init(selfBlockDescriptor(), base_block_t::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
}
// Alternatives are mutually exclusive wrt other Alternatives in the same block.
@@ -1447,7 +1608,7 @@ namespace LLInitParam
const Param* getCurrentChoice() const
{
- return BaseBlock::getParamFromHandle(mCurChoice);
+ return base_block_t::getParamFromHandle(mCurChoice);
}
};
@@ -1493,6 +1654,9 @@ namespace LLInitParam
typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
typedef typename super_t::value_assignment_t value_assignment_t;
+ using super_t::operator();
+ using super_t::operator=;
+
explicit Optional(const char* name = "", value_assignment_t val = defaultValue<T>())
: super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1)
{
@@ -1510,7 +1674,6 @@ namespace LLInitParam
super_t::set(val);
return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
}
- using super_t::operator();
};
template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
@@ -1521,6 +1684,9 @@ namespace LLInitParam
typedef Mandatory<T, NAME_VALUE_LOOKUP> self_t;
typedef typename super_t::value_assignment_t value_assignment_t;
+ using super_t::operator();
+ using super_t::operator=;
+
// mandatory parameters require a name to be parseable
explicit Mandatory(const char* name = "", value_assignment_t val = defaultValue<T>())
: super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, 1, 1)
@@ -1537,7 +1703,6 @@ namespace LLInitParam
super_t::set(val);
return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
}
- using super_t::operator();
static bool validate(const Param* p)
{
@@ -1693,14 +1858,12 @@ namespace LLInitParam
ParamValue()
: block_t(),
- mKeyVersion(0),
mValidatedVersion(-1),
mValidated(false)
{}
ParamValue(value_assignment_t other)
: block_t(other),
- mKeyVersion(0),
mValidatedVersion(-1),
mValidated(false)
{
@@ -1731,11 +1894,82 @@ namespace LLInitParam
return *this;
}
- S32 mKeyVersion;
+ protected:
+ mutable S32 mValidatedVersion;
+ mutable bool mValidated; // lazy validation flag
+ };
+
+ template<typename T>
+ class ParamValue <BaseBlock::Lazy<T>,
+ TypeValues<T>,
+ false>
+ {
+ public:
+ typedef ParamValue <BaseBlock::Lazy<T>, TypeValues<T>, false> self_t;
+ typedef const T& value_assignment_t;
+
+ ParamValue()
+ : mValue(),
+ mValidatedVersion(-1),
+ mValidated(false)
+ {}
+
+ ParamValue(value_assignment_t other)
+ : mValue(other),
+ mValidatedVersion(-1),
+ mValidated(false)
+ {}
+
+ void setValue(value_assignment_t val)
+ {
+ mValue.set(val);
+ }
+
+ value_assignment_t getValue() const
+ {
+ return mValue.get();
+ }
+
+ T& getValue()
+ {
+ return mValue.get();
+ }
+
+ operator value_assignment_t() const
+ {
+ return mValue.get();
+ }
+
+ value_assignment_t operator()() const
+ {
+ return mValue.get();
+ }
+
+ bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
+ {
+ return mValue.get().deserializeBlock(p, name_stack_range, new_name);
+ }
+
+ void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const
+ {
+ if (mValue.empty()) return;
+
+ mValue.get().serializeBlock(p, name_stack, diff_block);
+ }
+
+ bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
+ {
+ if (mValue.empty()) return false;
+
+ return mValue.get().inspectBlock(p, name_stack, min_count, max_count);
+ }
protected:
mutable S32 mValidatedVersion;
mutable bool mValidated; // lazy validation flag
+
+ private:
+ BaseBlock::Lazy<T> mValue;
};
template <>
@@ -1750,14 +1984,12 @@ namespace LLInitParam
typedef const LLSD& value_assignment_t;
ParamValue()
- : mKeyVersion(0),
- mValidatedVersion(-1),
+ : mValidatedVersion(-1),
mValidated(false)
{}
ParamValue(value_assignment_t other)
: mValue(other),
- mKeyVersion(0),
mValidatedVersion(-1),
mValidated(false)
{}
@@ -1770,7 +2002,6 @@ namespace LLInitParam
operator value_assignment_t() const { return mValue; }
value_assignment_t operator()() const { return mValue; }
- S32 mKeyVersion;
// block param interface
bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
@@ -1812,7 +2043,6 @@ namespace LLInitParam
CustomParamValue(const T& value = T())
: mValue(value),
mValueAge(VALUE_AUTHORITATIVE),
- mKeyVersion(0),
mValidatedVersion(-1),
mValidated(false)
{}
@@ -1966,8 +2196,6 @@ namespace LLInitParam
return getValue();
}
- S32 mKeyVersion;
-
protected:
// use this from within updateValueFromBlock() to set the value without making it authoritative
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index 878f992178..cdf578113a 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -59,28 +59,26 @@ const char* NO_VALUE_MARKER = "no_value";
const S32 LINE_NUMBER_HERE = 0;
-struct MaxOccur : public LLInitParam::ChoiceBlock<MaxOccur>
+struct MaxOccursValues : public LLInitParam::TypeValuesHelper<U32, MaxOccursValues>
{
- Alternative<int> count;
- Alternative<std::string> unbounded;
-
- MaxOccur()
- : unbounded("", "unbounded")
- {}
+ using TypeValuesHelper<U32, MaxOccursValues>::operator =;
+ typedef std::string name_t;
+ static void declareValues()
+ {
+ declare("unbounded", U32_MAX);
+ }
};
struct Occurs : public LLInitParam::Block<Occurs>
{
- Optional<S32> minOccurs;
- Optional<MaxOccur> maxOccurs;
+ Optional<U32> minOccurs;
+ Optional<U32, MaxOccursValues> maxOccurs;
+ Multiple<U32, AnyAmount, MaxOccursValues> foo;
Occurs()
- : minOccurs("minOccurs"),
- maxOccurs("maxOccurs")
- {
- minOccurs = 0;
- maxOccurs.unbounded.choose();
- }
+ : minOccurs("minOccurs", 0),
+ maxOccurs("maxOccurs", U32_MAX)
+ {}
};
@@ -103,18 +101,15 @@ namespace LLInitParam
};
}
-struct Name : public LLInitParam::Block<Name>
-{
- Mandatory<std::string> name;
-
- Name()
- : name("name")
- {}
-};
+struct Element;
+struct Group;
+struct Choice;
+struct Sequence;
+struct Any;
struct Attribute : public LLInitParam::Block<Attribute>
{
- Mandatory<Name> name;
+ Mandatory<std::string> name;
Mandatory<std::string> type;
Mandatory<EUse> use;
@@ -122,41 +117,170 @@ struct Attribute : public LLInitParam::Block<Attribute>
: name("name"),
type("type"),
use("use")
+ {}
+};
+
+struct Any : public LLInitParam::Block<Any, Occurs>
+{
+ Optional<std::string> _namespace;
+
+ Any()
+ : _namespace("namespace")
+ {}
+};
+
+struct All : public LLInitParam::Block<All, Occurs>
+{
+ Multiple<Lazy<Element>> elements;
+
+ All()
+ : elements("element")
{
+ maxOccurs = 1;
}
};
-struct ComplexType : public LLInitParam::Block<ComplexType>
+struct Choice : public LLInitParam::ChoiceBlock<Choice, Occurs>
+{
+ Alternative<Lazy<Element>> element;
+ Alternative<Lazy<Group>> group;
+ Alternative<Lazy<Choice>> choice;
+ Alternative<Lazy<Sequence>> sequence;
+ Alternative<Lazy<Any>> any;
+
+ Choice()
+ : element("element"),
+ group("group"),
+ choice("choice"),
+ sequence("sequence"),
+ any("any")
+ {}
+
+};
+
+struct Sequence : public LLInitParam::ChoiceBlock<Sequence, Occurs>
+{
+ Alternative<Lazy<Element>> element;
+ Alternative<Lazy<Group>> group;
+ Alternative<Lazy<Choice>> choice;
+ Alternative<Lazy<Sequence>> sequence;
+ Alternative<Lazy<Any>> any;
+};
+
+struct GroupContents : public LLInitParam::ChoiceBlock<GroupContents, Occurs>
{
- Multiple<Attribute> attribute;
- //Multiple<struct Element> elements;
- Optional<bool> mixed;
+ Alternative<All> all;
+ Alternative<Choice> choice;
+ Alternative<Sequence> sequence;
+
+ GroupContents()
+ : all("all"),
+ choice("choice"),
+ sequence("sequence")
+ {}
+};
+
+struct Group : public LLInitParam::Block<Group, GroupContents>
+{
+ Optional<std::string> name,
+ ref;
+
+ Group()
+ : name("name"),
+ ref("ref")
+ {}
+};
+
+struct Restriction : public LLInitParam::Block<Restriction>
+{
+};
+
+struct Extension : public LLInitParam::Block<Extension>
+{
+};
+
+struct SimpleContent : public LLInitParam::ChoiceBlock<SimpleContent>
+{
+ Alternative<Restriction> restriction;
+ Alternative<Extension> extension;
+
+ SimpleContent()
+ : restriction("restriction"),
+ extension("extension")
+ {}
+};
+
+struct SimpleType : public LLInitParam::Block<SimpleType>
+{
+ // TODO
+};
+
+struct ComplexContent : public LLInitParam::Block<ComplexContent, SimpleContent>
+{
+ Optional<bool> mixed;
+
+ ComplexContent()
+ : mixed("mixed", true)
+ {}
+};
+
+struct ComplexTypeContents : public LLInitParam::ChoiceBlock<ComplexTypeContents>
+{
+ Alternative<SimpleContent> simple_content;
+ Alternative<ComplexContent> complex_content;
+ Alternative<Group> group;
+ Alternative<All> all;
+ Alternative<Choice> choice;
+ Alternative<Sequence> sequence;
+
+ ComplexTypeContents()
+ : simple_content("simpleContent"),
+ complex_content("complexContent"),
+ group("group"),
+ all("all"),
+ choice("choice"),
+ sequence("sequence")
+ {}
+};
+
+struct ComplexType : public LLInitParam::Block<ComplexType, ComplexTypeContents>
+{
+ Optional<std::string> name;
+ Optional<bool> mixed;
+
+ Multiple<Attribute> attribute;
+ Multiple<Lazy<Element>> elements;
ComplexType()
- : attribute("xs:attribute"),
- //elements("xs:element"),
+ : name("name"),
+ attribute("xs:attribute"),
+ elements("xs:element"),
mixed("mixed")
{
- mixed = true;
}
};
-struct Element : public LLInitParam::Block<Element, Occurs>
+struct ElementContents : public LLInitParam::ChoiceBlock<ElementContents, Occurs>
{
- Mandatory<ComplexType> complexType;
- Mandatory<Name> name;
+ Alternative<SimpleType> simpleType;
+ Alternative<ComplexType> complexType;
- Element()
- : complexType("xs:complexType")
+ ElementContents()
+ : simpleType("simpleType"),
+ complexType("complexType")
{}
};
-struct Elements : public LLInitParam::Block<Elements, Occurs>
+struct Element : public LLInitParam::Block<Element, ElementContents>
{
- Multiple<Element> elements;
+ Optional<std::string> name,
+ ref,
+ type;
- Elements()
- : elements("xs:element")
+ Element()
+ : name("xs:name"),
+ ref("xs:ref"),
+ type("xs:type")
{}
};
@@ -164,28 +288,32 @@ struct Schema : public LLInitParam::Block<Schema>
{
private:
Mandatory<std::string> targetNamespace,
- xmlns;
+ xmlns,
+ xs;
public:
Optional<std::string> attributeFormDefault,
- elementFormDefault,
- xs;
+ elementFormDefault;
- Optional<Elements> elements;
+ Mandatory<Element> root_element;
void setNameSpace(const std::string& ns) {targetNamespace = ns; xmlns = ns;}
- Schema()
+ Schema(const std::string& ns = LLStringUtil::null)
: attributeFormDefault("attributeFormDefault"),
elementFormDefault("elementFormDefault"),
xs("xmlns:xs"),
targetNamespace("targetNamespace"),
xmlns("xmlns"),
- elements("xs:choice")
+ root_element("xs:element")
{
attributeFormDefault = "unqualified";
elementFormDefault = "qualified";
xs = "http://www.w3.org/2001/XMLSchema";
+ if (!ns.empty())
+ {
+ setNameSpace(ns);
+ };
}
};
@@ -214,22 +342,30 @@ LLXSDWriter::LLXSDWriter()
void LLXSDWriter::writeXSD(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace)
{
+ Schema schema(xml_namespace);
+
+ schema.root_element.name = type_name;
+ Choice& choice = schema.root_element.complexType.choice;
+
+ choice.minOccurs = 0;
+ choice.maxOccurs = "unbounded";
+
mSchemaNode = node;
- node->setName("xs:schema");
- node->createChild("attributeFormDefault", true)->setStringValue("unqualified");
- node->createChild("elementFormDefault", true)->setStringValue("qualified");
- node->createChild("targetNamespace", true)->setStringValue(xml_namespace);
- node->createChild("xmlns:xs", true)->setStringValue("http://www.w3.org/2001/XMLSchema");
- node->createChild("xmlns", true)->setStringValue(xml_namespace);
-
- node = node->createChild("xs:complexType", false);
- node->createChild("name", true)->setStringValue(type_name);
- node->createChild("mixed", true)->setStringValue("true");
-
- mAttributeNode = node;
- mElementNode = node->createChild("xs:choice", false);
- mElementNode->createChild("minOccurs", true)->setStringValue("0");
- mElementNode->createChild("maxOccurs", true)->setStringValue("unbounded");
+ //node->setName("xs:schema");
+ //node->createChild("attributeFormDefault", true)->setStringValue("unqualified");
+ //node->createChild("elementFormDefault", true)->setStringValue("qualified");
+ //node->createChild("targetNamespace", true)->setStringValue(xml_namespace);
+ //node->createChild("xmlns:xs", true)->setStringValue("http://www.w3.org/2001/XMLSchema");
+ //node->createChild("xmlns", true)->setStringValue(xml_namespace);
+
+ //node = node->createChild("xs:complexType", false);
+ //node->createChild("name", true)->setStringValue(type_name);
+ //node->createChild("mixed", true)->setStringValue("true");
+
+ //mAttributeNode = node;
+ //mElementNode = node->createChild("xs:choice", false);
+ //mElementNode->createChild("minOccurs", true)->setStringValue("0");
+ //mElementNode->createChild("maxOccurs", true)->setStringValue("unbounded");
block.inspectBlock(*this);
// duplicate element choices