diff options
Diffstat (limited to 'indra/llxuixml')
| -rw-r--r-- | indra/llxuixml/llinitparam.cpp | 56 | ||||
| -rw-r--r-- | indra/llxuixml/llinitparam.h | 638 | ||||
| -rw-r--r-- | indra/llxuixml/llxuiparser.cpp | 218 | ||||
| -rw-r--r-- | indra/llxuixml/llxuiparser.h | 42 | 
4 files changed, 539 insertions, 415 deletions
| diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp index c024fd405e..482064ed7b 100644 --- a/indra/llxuixml/llinitparam.cpp +++ b/indra/llxuixml/llinitparam.cpp @@ -62,7 +62,6 @@ namespace LLInitParam  		mInspectFunc(inspect_func),  		mMinCount(min_count),  		mMaxCount(max_count), -		mGeneration(0),  		mUserData(NULL)  	{} @@ -75,7 +74,6 @@ namespace LLInitParam  		mInspectFunc(NULL),  		mMinCount(0),  		mMaxCount(0), -		mGeneration(0),  		mUserData(NULL)  	{} @@ -87,8 +85,6 @@ namespace LLInitParam  	//  	// Parser  	// -	S32 Parser::sNextParseGeneration = 0; -  	Parser::~Parser()  	{} @@ -162,9 +158,9 @@ namespace LLInitParam  		return (param_address - baseblock_address);  	} -	bool BaseBlock::submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent) +	bool BaseBlock::submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent)  	{ -		if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()), -1)) +		if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()), true))  		{  			if (!silent)  			{ @@ -194,7 +190,7 @@ namespace LLInitParam  		return true;  	} -	void 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 @@ -213,8 +209,7 @@ namespace LLInitParam  				// each param descriptor remembers its serial number  				// so we can inspect the same param under different names  				// and see that it has the same number -				(*it)->mGeneration = parser.newParseGeneration(); -				name_stack.push_back(std::make_pair("", (*it)->mGeneration)); +				name_stack.push_back(std::make_pair("", true));  				serialize_func(*param, parser, name_stack, diff_param);  				name_stack.pop_back();  			} @@ -250,12 +245,7 @@ namespace LLInitParam  					continue;  				} -				if (!duplicate) -				{ -					it->second->mGeneration = parser.newParseGeneration(); -				} - -				name_stack.push_back(std::make_pair(it->first, it->second->mGeneration)); +				name_stack.push_back(std::make_pair(it->first, !duplicate));  				const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;  				serialize_func(*param, parser, name_stack, diff_param);  				name_stack.pop_back(); @@ -278,8 +268,7 @@ namespace LLInitParam  			ParamDescriptor::inspect_func_t inspect_func = (*it)->mInspectFunc;  			if (inspect_func)  			{ -				(*it)->mGeneration = parser.newParseGeneration(); -				name_stack.push_back(std::make_pair("", (*it)->mGeneration)); +				name_stack.push_back(std::make_pair("", true));  				inspect_func(*param, parser, name_stack, (*it)->mMinCount, (*it)->mMaxCount);  				name_stack.pop_back();  			} @@ -307,11 +296,7 @@ namespace LLInitParam  					}  				} -				if (!duplicate) -				{ -					it->second->mGeneration = parser.newParseGeneration(); -				} -				name_stack.push_back(std::make_pair(it->first, it->second->mGeneration)); +				name_stack.push_back(std::make_pair(it->first, !duplicate));  				inspect_func(*param, parser, name_stack, it->second->mMinCount, it->second->mMaxCount);  				name_stack.pop_back();  			} @@ -320,16 +305,18 @@ namespace LLInitParam  		return true;  	} -	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 parent_generation) +	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool ignored)  	{  		BlockDescriptor& block_data = mostDerivedBlockDescriptor(); -		bool names_left = name_stack.first != name_stack.second; +		bool names_left = name_stack_range.first != name_stack_range.second; -		S32 parse_generation = name_stack.first == name_stack.second ? -1 : name_stack.first->second; +		bool new_name = names_left +						? name_stack_range.first->second +						: true;  		if (names_left)  		{ -			const std::string& top_name = name_stack.first->first; +			const std::string& top_name = name_stack_range.first->first;  			ParamDescriptor::deserialize_func_t deserialize_func = NULL;  			Param* paramp = NULL; @@ -341,9 +328,18 @@ namespace LLInitParam  				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); +				Parser::name_stack_range_t new_name_stack(name_stack_range.first, name_stack_range.second);  				++new_name_stack.first; -				return deserialize_func(*paramp, p, new_name_stack, parse_generation); +				if (deserialize_func(*paramp, p, new_name_stack, new_name)) +				{ +					// value is no longer new, we know about it now +					name_stack_range.first->second = false; +					return true; +				} +				else +				{ +					return false; +				}  			}  		} @@ -355,7 +351,7 @@ namespace LLInitParam  			Param* paramp = getParamFromHandle((*it)->mParamHandle);  			ParamDescriptor::deserialize_func_t deserialize_func = (*it)->mDeserializeFunc; -			if (deserialize_func && deserialize_func(*paramp, p, name_stack, parse_generation)) +			if (deserialize_func && deserialize_func(*paramp, p, name_stack_range, new_name))  			{  				return true;  			} @@ -365,7 +361,7 @@ namespace LLInitParam  		// verify by calling readValue with NoParamValue type, an inherently unparseable type  		if (!names_left)  		{ -			NoParamValue no_value; +			Flag no_value;  			return p.readValue(no_value);  		} diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index 69dcd474f7..1e295ada2d 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -38,6 +38,9 @@  namespace LLInitParam  { +	// used to indicate no matching value to a given name when parsing +	struct Flag{}; +  	template<typename T> const T& defaultValue() { static T value; return value; }  	template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value > @@ -65,6 +68,12 @@ namespace LLInitParam  		static bool equals(const LLSD &a, const LLSD &b) { return false; }  	}; +	template<> +	struct ParamCompare<Flag, false> +	{ +		static bool equals(const Flag& a, const Flag& b) { return false; } +	}; +  	// helper functions and classes  	typedef ptrdiff_t param_handle_t; @@ -78,6 +87,7 @@ namespace LLInitParam  		void setValueName(const std::string& key) {}  		std::string getValueName() const { return ""; } +		std::string calcValueName(const T& value) const { return ""; }  		void clearValueName() const {}  		static bool getValueFromName(const std::string& name, T& value) @@ -115,6 +125,22 @@ namespace LLInitParam  			return mValueName;   		} +		std::string calcValueName(const T& value) const +		{ +			value_name_map_t* map = getValueNames(); +			for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end(); +				it != end_it; +				++it) +			{ +				if (ParamCompare<T>::equals(it->second, value)) +				{ +					return it->first; +				} +			} + +			return ""; +		} +  		void clearValueName() const  		{  			mValueName.clear(); @@ -188,13 +214,13 @@ namespace LLInitParam  			}  		}; -		typedef std::vector<std::pair<std::string, S32> >								name_stack_t; -		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 std::vector<std::pair<std::string, bool> >					name_stack_t; +		typedef std::pair<name_stack_t::iterator, name_stack_t::iterator>	name_stack_range_t; +		typedef std::vector<std::string>									possible_values_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 bool (*parser_write_func_t)(Parser& parser, const void*, name_stack_t&); +		typedef boost::function<void (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; @@ -202,7 +228,6 @@ namespace LLInitParam  		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(sNextParseGeneration),  			mParserReadFuncs(&read_map),  			mParserWriteFuncs(&write_map),  			mParserInspectFuncs(&inspect_map) @@ -219,7 +244,7 @@ namespace LLInitParam  		    return false;  	    } -		template <typename T> bool writeValue(const T& param, const name_stack_t& name_stack) +		template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)  		{  		    parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T));  		    if (found_it != mParserWriteFuncs->end()) @@ -230,7 +255,7 @@ 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) +		template <typename T> bool inspectValue(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()) @@ -246,10 +271,6 @@ namespace LLInitParam  		virtual void parserError(const std::string& message);  		void setParseSilently(bool silent) { mParseSilently = silent; } -		S32 getParseGeneration() { return mParseGeneration; } -		S32 newParseGeneration() { return mParseGeneration = ++sNextParseGeneration; } - -  	protected:  		template <typename T>  		void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func = NULL) @@ -270,14 +291,8 @@ namespace LLInitParam  		parser_read_func_map_t*		mParserReadFuncs;  		parser_write_func_map_t*	mParserWriteFuncs;  		parser_inspect_func_map_t*	mParserInspectFuncs; -		S32	mParseGeneration; - -		static S32					sNextParseGeneration;  	}; -	// used to indicate no matching value to a given name when parsing -	struct NoParamValue{}; -  	class BaseBlock;  	class Param @@ -318,7 +333,7 @@ namespace LLInitParam  		};  		typedef bool(*merge_func_t)(Param&, const Param&, bool); -		typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, S32); +		typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, bool);  		typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param);  		typedef void(*inspect_func_t)(const Param&, Parser&, Parser::name_stack_t&, S32 min_count, S32 max_count);  		typedef bool(*validation_func_t)(const Param*); @@ -343,7 +358,6 @@ namespace LLInitParam  		validation_func_t	mValidationFunc;  		S32					mMinCount;  		S32					mMaxCount; -		S32					mGeneration;  		S32					mNumRefs;  		UserData*			mUserData;  	}; @@ -385,36 +399,36 @@ namespace LLInitParam  		// "Multiple" constraint types, put here in root class to avoid ambiguity during use  		struct AnyAmount  		{ -			static U32 minCount() { return 0; } -			static U32 maxCount() { return U32_MAX; } +			enum { minCount = 0 }; +			enum { maxCount = U32_MAX };  		};  		template<U32 MIN_AMOUNT>  		struct AtLeast  		{ -			static U32 minCount() { return MIN_AMOUNT; } -			static U32 maxCount() { return U32_MAX; } +			enum { minCount = MIN_AMOUNT }; +			enum { maxCount = U32_MAX };  		};  		template<U32 MAX_AMOUNT>  		struct AtMost  		{ -			static U32 minCount() { return 0; } -			static U32 maxCount() { return MAX_AMOUNT; } +			enum { minCount = 0 }; +			enum { maxCount = MAX_AMOUNT };  		};  		template<U32 MIN_AMOUNT, U32 MAX_AMOUNT>  		struct Between  		{ -			static U32 minCount() { return MIN_AMOUNT; } -			static U32 maxCount() { return MAX_AMOUNT; } +			enum { minCount = MIN_AMOUNT }; +			enum { maxCount = MAX_AMOUNT };  		};  		template<U32 EXACT_COUNT>  		struct Exactly  		{ -			static U32 minCount() { return EXACT_COUNT; } -			static U32 maxCount() { return EXACT_COUNT; } +			enum { minCount = EXACT_COUNT }; +			enum { maxCount = EXACT_COUNT };  		};  		// this typedef identifies derived classes as being blocks @@ -424,7 +438,7 @@ namespace LLInitParam  		BaseBlock();  		virtual ~BaseBlock(); -		bool submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent=false); +		bool submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent=false);  		param_handle_t getHandleFromParam(const Param* param) const;  		bool validateBlock(bool emit_errors = true) const; @@ -450,8 +464,8 @@ namespace LLInitParam  		S32 getLastChangeVersion() const { return mChangeVersion; } -		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation); -		void serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const; +		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name); +		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;  		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;  		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } @@ -477,9 +491,9 @@ namespace LLInitParam  		void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size); -		bool mergeBlockParam(bool param_provided, BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) +		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)  		{ -			return mergeBlock(block_data, other, overwrite); +			return mergeBlock(block_data, source, overwrite);  		}  		// take all provided params from other and apply to self  		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite); @@ -497,92 +511,6 @@ namespace LLInitParam  		const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;  	}; -	class BaseBlockWithFlags : public BaseBlock -	{ -	public: -		class FlagBase : public Param -		{ -		public: -			typedef FlagBase self_t; - -			FlagBase(const char* name, BaseBlock* enclosing_block) : Param(enclosing_block)  -			{ -				if (LL_UNLIKELY(enclosing_block->mostDerivedBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING)) -				{ -					ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( -						enclosing_block->getHandleFromParam(this), -						&mergeWith, -						&deserializeParam, -						&serializeParam, -						NULL, -						&inspectParam, -						0, 1)); -					BaseBlock::addParam(enclosing_block->mostDerivedBlockDescriptor(), param_descriptor, name); -				} -			} - -			bool isProvided() const { return anyProvided(); } - -		private: -			static bool mergeWith(Param& dst, const Param& src, bool overwrite) -			{ -				const self_t& src_typed_param = static_cast<const self_t&>(src); -				self_t& dst_typed_param = static_cast<self_t&>(dst); - -				if (src_typed_param.isProvided() -					&& (overwrite || !dst_typed_param.isProvided())) -				{ -					dst.setProvided(true); -					return true; -				} -				return false; -			} - -			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); - -				// no further names in stack, parse value now -				if (name_stack.first == name_stack.second) -				{ -					typed_param.setProvided(true); -					typed_param.enclosingBlock().paramChanged(param, true); -					return true; -				} - -				return false; -			} - -			static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param) -			{ -				const self_t& typed_param = static_cast<const self_t&>(param); -				const self_t* typed_diff_param = static_cast<const self_t*>(diff_param); - -				if (!typed_param.isProvided()) return; - -				if (!name_stack.empty()) -				{ -					name_stack.back().second = parser.newParseGeneration(); -				} - -				// then try to serialize value directly -				if (!typed_diff_param || !typed_diff_param->isProvided()) -				{ -					if (!parser.writeValue(NoParamValue(), name_stack))  -					{ -						return; -					} -				} -			} - -			static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count) -			{ -				// tell parser about our actual type -				parser.inspectValue<NoParamValue>(name_stack, min_count, max_count, NULL); -			} -		}; -	}; -  	// these templates allow us to distinguish between template parameters  	// that derive from BaseBlock and those that don't  	template<typename T, typename Void = void> @@ -604,7 +532,7 @@ namespace LLInitParam  		typedef const T&							value_assignment_t;  		ParamValue(): mValue() {} -		ParamValue(const T& other) : mValue(other) {} +		ParamValue(value_assignment_t other) : mValue(other) {}  		void setValue(value_assignment_t val)  		{ @@ -621,6 +549,17 @@ namespace LLInitParam  			return mValue;  		} +		operator value_assignment_t() const +		{ +			return mValue; +		} + +		value_assignment_t operator()() const +		{ +			return mValue; +		} + +  	private:  		T mValue;  	}; @@ -633,10 +572,6 @@ namespace LLInitParam  	public:  		typedef const T&							value_assignment_t; -		S32 			mKeyVersion; -		mutable S32 	mValidatedVersion; -		mutable bool 	mValidated; // lazy validation flag -  		ParamValue()   		:	T(),  			mKeyVersion(0), @@ -644,13 +579,12 @@ namespace LLInitParam  			mValidated(false)  		{} -		ParamValue(const T& other) +		ParamValue(value_assignment_t other)  		:	T(other),  			mKeyVersion(0),  			mValidatedVersion(-1),  			mValidated(false) -		{ -		} +		{}  		void setValue(value_assignment_t val)  		{ @@ -666,6 +600,22 @@ namespace LLInitParam  		{  			return *this;  		} + +		operator value_assignment_t() const +		{ +			return *this; +		} +		 +		value_assignment_t operator()() const +		{ +			return *this; +		} + +		S32 			mKeyVersion; + +	protected: +		mutable S32 	mValidatedVersion; +		mutable bool 	mValidated; // lazy validation flag  	};  	template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> > @@ -712,11 +662,11 @@ namespace LLInitParam  		bool isProvided() const { return Param::anyProvided(); } -		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)  +		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)  		{   			self_t& typed_param = static_cast<self_t&>(param);  			// no further names in stack, attempt to parse value now -			if (name_stack.first == name_stack.second) +			if (name_stack_range.first == name_stack_range.second)  			{  				if (parser.readValue(typed_param.getValue()))  				{ @@ -755,7 +705,7 @@ namespace LLInitParam  			if (!name_stack.empty())  			{ -				name_stack.back().second = parser.newParseGeneration(); +				name_stack.back().second = true;  			}  			std::string key = typed_param.getValueName(); @@ -766,10 +716,7 @@ namespace LLInitParam  			{  				if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))  				{ -					if (!parser.writeValue(key, name_stack)) -					{ -						return; -					} +					parser.writeValue(key, name_stack);  				}  			}  			// then try to serialize value directly @@ -777,7 +724,11 @@ namespace LLInitParam  			{  				if (!parser.writeValue(typed_param.getValue(), name_stack))   				{ -					return; +					std::string calculated_key = typed_param.calcValueName(typed_param.getValue()); +					if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key)) +					{ +						parser.writeValue(calculated_key, name_stack); +					}  				}  			}  		} @@ -801,11 +752,6 @@ namespace LLInitParam  			Param::enclosingBlock().paramChanged(*this, flag_as_provided);  		} -		// implicit conversion -		operator value_assignment_t() const { return param_value_t::getValue(); }  -		// explicit conversion -		value_assignment_t operator()() const { return param_value_t::getValue(); }  -  	protected:  		static bool mergeWith(Param& dst, const Param& src, bool overwrite) @@ -855,11 +801,11 @@ namespace LLInitParam  			}  		} -		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)  +		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)  		{   			self_t& typed_param = static_cast<self_t&>(param);  			// attempt to parse block... -			if(typed_param.deserializeBlock(parser, name_stack, generation)) +			if(typed_param.deserializeBlock(parser, name_stack_range, new_name))  			{  				typed_param.clearValueName();  				typed_param.enclosingBlock().paramChanged(param, true); @@ -895,7 +841,7 @@ namespace LLInitParam  			if (!name_stack.empty())  			{ -				name_stack.back().second = parser.newParseGeneration(); +				name_stack.back().second = true;  			}  			std::string key = typed_param.getValueName(); @@ -958,11 +904,6 @@ namespace LLInitParam  			}  		} -		// implicit conversion -		operator value_assignment_t() const { return param_value_t::getValue(); }  -		// explicit conversion -		value_assignment_t operator()() const { return param_value_t::getValue(); }  -  	protected:  		static bool mergeWith(Param& dst, const Param& src, bool overwrite) @@ -972,8 +913,7 @@ namespace LLInitParam  			if (src_typed_param.anyProvided())  			{ -				bool param_provided = src_typed_param.isProvided() && (overwrite || !dst_typed_param.isProvided()); -				if (dst_typed_param.mergeBlockParam(param_provided, param_value_t::selfBlockDescriptor(), src_typed_param, overwrite)) +				if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::selfBlockDescriptor(), src_typed_param, overwrite))  				{  					dst_typed_param.clearValueName();  					dst_typed_param.setProvided(true); @@ -992,7 +932,7 @@ namespace LLInitParam  	{  	public:  		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false>		self_t; -		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>			param_value_t; +		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>					param_value_t;  		typedef typename std::vector<param_value_t>							container_t;  		typedef const container_t&											value_assignment_t; @@ -1020,12 +960,12 @@ namespace LLInitParam  		bool isProvided() const { return Param::anyProvided(); } -		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)  +		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)  		{   			self_t& typed_param = static_cast<self_t&>(param);  			value_t value;  			// no further names in stack, attempt to parse value now -			if (name_stack.first == name_stack.second) +			if (name_stack_range.first == name_stack_range.second)  			{  				// attempt to read value directly  				if (parser.readValue(value)) @@ -1065,14 +1005,19 @@ namespace LLInitParam  				++it)  			{  				std::string key = it->getValue(); -				name_stack.back().second = parser.newParseGeneration(); +				name_stack.back().second = true;  				if(key.empty())  				// not parsed via name values, write out value directly  				{ -					if (!parser.writeValue(*it, name_stack)) +					bool value_written = parser.writeValue(*it, name_stack); +					if (!value_written)  					{ -						break; +						std::string calculated_key = typed_param.calcValueName(typed_param.getValue()); +						if (!parser.writeValue(calculated_key, name_stack)) +						{ +							break; +						}  					}  				}  				else  @@ -1118,6 +1063,8 @@ namespace LLInitParam  		// implicit conversion  		operator value_assignment_t() const { return mValues; }  +		// explicit conversion		 +		value_assignment_t operator()() const { return mValues; }  		typedef typename container_t::iterator iterator;  		typedef typename container_t::const_iterator const_iterator; @@ -1169,14 +1116,13 @@ 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;  		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  -		:	Param(block_descriptor.mCurrentBlockPtr), -			mLastParseGeneration(0) +		:	Param(block_descriptor.mCurrentBlockPtr)  		{  			std::copy(value.begin(), value.end(), back_inserter(mValues)); @@ -1196,13 +1142,12 @@ namespace LLInitParam  		bool isProvided() const { return Param::anyProvided(); } -		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)  +		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)   		{   			self_t& typed_param = static_cast<self_t&>(param);  			bool new_value = false; -			if (generation != typed_param.mLastParseGeneration  -				|| typed_param.mValues.empty()) +			if (new_name || typed_param.mValues.empty())  			{  				new_value = true;  				typed_param.mValues.push_back(value_t()); @@ -1211,12 +1156,8 @@ namespace LLInitParam  			param_value_t& value = typed_param.mValues.back();  			// attempt to parse block... -			if(value.deserializeBlock(parser, name_stack, generation)) +			if(value.deserializeBlock(parser, name_stack_range, new_name))  			{ -				if (new_value) -				{	// successfully parsed new value, let's keep it -					typed_param.mLastParseGeneration = generation; -				}  				typed_param.enclosingBlock().paramChanged(param, true);  				typed_param.setProvided(true);  				return true; @@ -1230,11 +1171,6 @@ namespace LLInitParam  					// try to parse a per type named value  					if (name_value_lookup_t::getValueFromName(name, value.getValue()))  					{ -						if (new_value) -						{	// successfully parsed new value, let's keep it -							typed_param.mLastParseGeneration = generation; -						} -  						typed_param.mValues.back().setValueName(name);  						typed_param.mValues.back().mKeyVersion = value.getLastChangeVersion();  						typed_param.enclosingBlock().paramChanged(param, true); @@ -1262,7 +1198,7 @@ namespace LLInitParam  				it != end_it;  				++it)  			{ -				name_stack.back().second = parser.newParseGeneration(); +				name_stack.back().second = true;  				std::string key = it->getValueName();  				if (!key.empty() && it->mKeyVersion == it->getLastChangeVersion()) @@ -1308,6 +1244,8 @@ namespace LLInitParam  		// implicit conversion  		operator value_assignment_t() const { return mValues; }  +		// explicit conversion +		value_assignment_t operator()() const { return mValues; }  		typedef typename container_t::iterator iterator;  		typedef typename container_t::const_iterator const_iterator; @@ -1358,15 +1296,13 @@ namespace LLInitParam  		}  		container_t			mValues; - -		S32			mLastParseGeneration;  	};  	template <typename DERIVED_BLOCK> -	class Choice : public BaseBlock +	class ChoiceBlock : public BaseBlock  	{ -		typedef Choice<DERIVED_BLOCK>	self_t; -		typedef Choice<DERIVED_BLOCK>	enclosing_block_t; +		typedef ChoiceBlock<DERIVED_BLOCK>	self_t; +		typedef ChoiceBlock<DERIVED_BLOCK>	enclosing_block_t;  		LOG_CLASS(self_t);  	public: @@ -1382,11 +1318,13 @@ namespace LLInitParam  			return mergeBlock(selfBlockDescriptor(), other, false);  		} -		bool mergeBlockParam(bool param_provided, BlockDescriptor& block_data, const self_t& other, bool overwrite) +		bool mergeBlockParam(bool source_provided, bool dest_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)  		{ -			if (param_provided) +			bool source_override = source_provided && (overwrite || !dest_provided); + +			if (source_override || source.mCurChoice == mCurChoice)  			{ -				return mergeBlock(block_data, other, overwrite); +				return mergeBlock(block_data, source, overwrite);  			}  			return false;  		} @@ -1420,7 +1358,7 @@ namespace LLInitParam  		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }  	protected: -		Choice() +		ChoiceBlock()  		:	mCurChoice(0)  		{  			BaseBlock::init(selfBlockDescriptor(), BaseBlock::selfBlockDescriptor(), sizeof(DERIVED_BLOCK)); @@ -1433,13 +1371,13 @@ namespace LLInitParam  		class Alternative : public TypedParam<T, NAME_VALUE_LOOKUP, false>  		{  		public: -			friend class Choice<DERIVED_BLOCK>; +			friend class ChoiceBlock<DERIVED_BLOCK>;  			typedef Alternative<T, NAME_VALUE_LOOKUP>									self_t;  			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; -			explicit Alternative(const char* name, value_assignment_t val = defaultValue<T>()) +			explicit Alternative(const char* name = "", value_assignment_t val = defaultValue<T>())  			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),  				mOriginalValue(val)  			{ @@ -1454,10 +1392,19 @@ namespace LLInitParam  				}  			} -			Alternative& operator=(value_assignment_t val) +			void choose() +			{ +				static_cast<enclosing_block_t&>(Param::enclosingBlock()).paramChanged(*this, true); +			} + +			void chooseAs(value_assignment_t val) +			{ +				super_t::set(val); +			} + +			void operator=(value_assignment_t val)  			{  				super_t::set(val); -				return *this;  			}  			void operator()(typename super_t::value_assignment_t val)  @@ -1466,12 +1413,8 @@ namespace LLInitParam  			}  			operator value_assignment_t() const  -			{  -				if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this) -				{ -					return super_t::getValue();  -				} -				return mOriginalValue; +			{ +				return (*this)();  			}   			value_assignment_t operator()() const  @@ -1508,7 +1451,7 @@ namespace LLInitParam  		}  	}; -	template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlockWithFlags> +	template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>  	class Block   	:	public BASE_BLOCK  	{ @@ -1604,13 +1547,6 @@ namespace LLInitParam  		}; -		class Flag : public BaseBlockWithFlags::FlagBase -		{ -		public: -			Flag(const char* name) : FlagBase(name, DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr) -			{} -		}; -  		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> >  		class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>  		{ @@ -1623,7 +1559,7 @@ namespace LLInitParam  			typedef typename super_t::const_iterator								const_iterator;  			explicit Multiple(const char* name = "") -			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount(), RANGE::maxCount()) +			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)  			{}  			Multiple& operator=(value_assignment_t val) @@ -1641,100 +1577,10 @@ namespace LLInitParam  			static bool validate(const Param* paramp)   			{  				U32 num_valid = ((super_t*)paramp)->numValidElements(); -				return RANGE::minCount() <= num_valid && num_valid <= RANGE::maxCount(); +				return RANGE::minCount <= num_valid && num_valid <= RANGE::maxCount;  			}  		}; -		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> > -		class Batch : private TypedParam<T, NAME_VALUE_LOOKUP, false> -		{ -		public: -			typedef ParamValue<T, NAME_VALUE_LOOKUP>										param_value_t; -			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<param_value_t>::value>	super_t; -			typedef Batch<T, RANGE, NAME_VALUE_LOOKUP>										self_t; -			typedef typename super_t::value_assignment_t									value_assignment_t; -			typedef typename super_t::value_t												value_t; - -			struct BatchDefaultValue : public ParamDescriptor::UserData -			{ -				BatchDefaultValue(const T& value) -				:	mValue(value) -				{} - -				T mValue; -			}; - -			explicit Batch(const char* name, value_assignment_t val) -			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1), -				mLastParseGeneration(-1) -			{ -				BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor(); -				if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)) -				{ -					ParamDescriptorPtr param_descriptorp = block_descriptor.mCurrentBlockPtr->findParamDescriptor(*this); - -					if (param_descriptorp) -					{ -						param_descriptorp->mDeserializeFunc = &deserializeParam; -						param_descriptorp->mUserData = new BatchDefaultValue(new param_value_t(val)); -					} -				} -			} - -			explicit Batch(const char* name = "") -			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, defaultValue<T>(), NULL, 0, 1), -				mLastParseGeneration(-1) -			{ -				BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor(); -				if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)) -				{ -					ParamDescriptorPtr param_descriptorp = block_descriptor.mCurrentBlockPtr->findParamDescriptor(*this); - -					if (param_descriptorp) -					{ -						param_descriptorp->mDeserializeFunc = &deserializeParam; -					} -				} -			} - -			Batch& operator=(value_assignment_t val) -			{ -				set(val); -				return *this; -			} - -			DERIVED_BLOCK& operator()(value_assignment_t val) -			{ -				super_t::set(val); -				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock()); -			} - -			using super_t::operator(); - -		private: -			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); - -				if (generation != typed_param.mLastParseGeneration) -				{ -					ParamDescriptorPtr descriptor = typed_param.enclosingBlock().findParamDescriptor(param); -					if (descriptor && static_cast<BatchDefaultValue*>(descriptor->mUserData)) -					{ -						static_cast<param_value_t&>(typed_param) = (static_cast<BatchDefaultValue*>(descriptor->mUserData))->mValue; -					} -					else -					{ -						static_cast<param_value_t&>(typed_param) = param_value_t(value_t()); -					} -					typed_param.mLastParseGeneration = generation; -				} -				return super_t::deserializeParam(param, parser, name_stack, generation); -			} - -			S32 mLastParseGeneration; -		}; -  		class Deprecated : public Param  		{  		public: @@ -1756,9 +1602,9 @@ namespace LLInitParam  				}  			} -			static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) +			static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)  			{ -				if (name_stack.first == name_stack.second) +				if (name_stack_range.first == name_stack_range.second)  				{  					//std::string message = llformat("Deprecated value %s ignored", getName().c_str());  					//parser.parserWarning(message); @@ -1769,6 +1615,7 @@ namespace LLInitParam  			}  		}; +		// different semantics for documentation purposes, but functionally identical  		typedef Deprecated Ignored;  	protected: @@ -1790,6 +1637,160 @@ namespace LLInitParam  	}; +	template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock> +	class BatchBlock +	:	public Block<DERIVED_BLOCK, BASE_BLOCK> +	{ +	public: +		typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> self_t; +		typedef Block<DERIVED_BLOCK, BASE_BLOCK> super_t; + +		BatchBlock() +		{} + +		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name) +		{ +			if (new_name) +			{ +				// reset block +				*static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue(); +			} +			return super_t::deserializeBlock(p, name_stack_range, new_name); +		} + +		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) +		{ +			if (overwrite) +			{ +				*static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue(); +				// merge individual parameters into destination +				return super_t::mergeBlock(super_t::selfBlockDescriptor(), other, overwrite); +			} +			return false; +		} +	protected: +		static const DERIVED_BLOCK& defaultBatchValue() +		{ +			static DERIVED_BLOCK default_value; +			return default_value; +		} +	}; + +	// FIXME: this specialization is not currently used, as it only matches against the BatchBlock base class +	// and not the derived class with the actual params +	template<typename DERIVED_BLOCK, +			typename BASE_BLOCK, +			typename NAME_VALUE_LOOKUP> +	class ParamValue <BatchBlock<DERIVED_BLOCK, BASE_BLOCK>, +					NAME_VALUE_LOOKUP, +					true> +	:	public NAME_VALUE_LOOKUP, +		protected BatchBlock<DERIVED_BLOCK, BASE_BLOCK> +	{ +	public: +		typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> block_t; +		typedef const BatchBlock<DERIVED_BLOCK, BASE_BLOCK>&	value_assignment_t; + +		ParamValue() +		:	block_t(), +			mKeyVersion(0), +			mValidatedVersion(-1), +			mValidated(false) +		{} + +		ParamValue(value_assignment_t other) +		:	block_t(other), +			mKeyVersion(0), +			mValidatedVersion(-1), +			mValidated(false) +		{ +		} + +		void setValue(value_assignment_t val) +		{ +			*this = val; +		} + +		value_assignment_t getValue() const +		{ +			return *this; +		} + +		BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& getValue() +		{ +			return *this; +		} + +		operator value_assignment_t() const +		{ +			return *this; +		} + +		value_assignment_t operator()() const +		{ +			return *this; +		} + +		S32 			mKeyVersion; + +	protected: +		mutable S32 	mValidatedVersion; +		mutable bool 	mValidated; // lazy validation flag +	}; + +	template <> +	class ParamValue <LLSD, +					TypeValues<LLSD>, +					false> +	:	public TypeValues<LLSD>, +		public BaseBlock +	{ +	public: +		typedef ParamValue<LLSD, TypeValues<LLSD>, false> self_t; +		typedef const LLSD&	value_assignment_t; + +		ParamValue() +		:	mKeyVersion(0), +			mValidatedVersion(-1), +			mValidated(false) +		{} + +		ParamValue(value_assignment_t other) +		:	mValue(other), +			mKeyVersion(0), +			mValidatedVersion(-1), +			mValidated(false) +		{} + +		void setValue(value_assignment_t val) { mValue = val; } + +		value_assignment_t getValue() const { return mValue; } +		LLSD& getValue() { return mValue; } + +		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); +		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const; +		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const +		{ +			//TODO: implement LLSD params as schema type Any +			return true; +		} + +	protected: +		mutable S32 	mValidatedVersion; +		mutable bool 	mValidated; // lazy validation flag + +	private: +		static void serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack); + +		LLSD mValue; +	}; +  	template<typename T>  	class CustomParamValue  	:	public Block<ParamValue<T, TypeValues<T> > >, @@ -1816,11 +1817,11 @@ namespace LLInitParam  			mValidated(false)  		{} -		bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack, S32 generation) +		bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack_range, bool new_name)  		{  			derived_t& typed_param = static_cast<derived_t&>(*this);  			// try to parse direct value T -			if (name_stack.first == name_stack.second) +			if (name_stack_range.first == name_stack_range.second)  			{  				if(parser.readValue(typed_param.mValue))  				{ @@ -1834,10 +1835,10 @@ namespace LLInitParam  			}  			// fall back on parsing block components for T -			return typed_param.BaseBlock::deserializeBlock(parser, name_stack, generation); +			return typed_param.BaseBlock::deserializeBlock(parser, name_stack_range, new_name);  		} -		void serializeBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const +		void serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const  		{  			const derived_t& typed_param = static_cast<const derived_t&>(*this);  			const derived_t* diff_param = static_cast<const derived_t*>(diff_block); @@ -1955,6 +1956,16 @@ namespace LLInitParam  			return mValue;  		} +		operator value_assignment_t() const +		{ +			return getValue(); +		} + +		value_assignment_t operator()() const +		{ +			return getValue(); +		} +  		S32 				mKeyVersion;  	protected: @@ -1965,30 +1976,29 @@ namespace LLInitParam  			mValue = value;  		} -		bool mergeBlockParam(bool param_provided, BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) +		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)  		{ -			if (param_provided) -			{ -				return mergeBlock(block_data, other, overwrite); -			} -			return false; -		} +			bool source_override = source_provided && (overwrite || !dst_provided); -		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) -		{ -			const derived_t& src_typed_param = static_cast<const derived_t&>(other); +			const derived_t& src_typed_param = static_cast<const derived_t&>(source); -			if (src_typed_param.mValueAge == VALUE_AUTHORITATIVE) +			if (source_override && src_typed_param.mValueAge == VALUE_AUTHORITATIVE)  			{  				// copy value over  				setValue(src_typed_param.getValue());  				return true;  			} -			else +			// merge individual parameters into destination +			if (mValueAge == VALUE_AUTHORITATIVE)  			{ -				// merge individual parameters into destination -				return block_t::mergeBlock(block_t::selfBlockDescriptor(), src_typed_param, overwrite); +				static_cast<derived_t*>(this)->updateBlockFromValue(dst_provided);  			} +			return mergeBlock(block_data, source, overwrite); +		} + +		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& source, bool overwrite) +		{ +			return block_t::mergeBlock(block_data, source, overwrite);  		}  		mutable S32			mValidatedVersion; diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index 4af077b22c..d4556113ea 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -51,6 +51,136 @@ static 	LLInitParam::Parser::parser_read_func_map_t sXSDReadFuncs;  static 	LLInitParam::Parser::parser_write_func_map_t sXSDWriteFuncs;  static 	LLInitParam::Parser::parser_inspect_func_map_t sXSDInspectFuncs; +struct MaxOccur : public LLInitParam::ChoiceBlock<MaxOccur> +{ +	Alternative<int> count; +	Alternative<std::string> unbounded; + +	MaxOccur() +	:	unbounded("", "unbounded") +	{} +}; + +struct Occurs : public LLInitParam::Block<Occurs> +{ +	Optional<S32>	minOccurs; +	Optional<MaxOccur>	maxOccurs; + +	Occurs() +	:	minOccurs("minOccurs"), +		maxOccurs("maxOccurs") +	{ +		minOccurs = 0; +		maxOccurs.unbounded.choose(); +	} +}; + + +typedef enum +{ +	USE_REQUIRED, +	USE_OPTIONAL +} EUse; + +namespace LLInitParam +{ +	template<> +	struct TypeValues<EUse> : public TypeValuesHelper<EUse> +	{ +		static void declareValues() +		{ +			declare("required", USE_REQUIRED); +			declare("optional", USE_OPTIONAL); +		} +	}; +} + +struct Name : public LLInitParam::Block<Name> +{ +	Mandatory<std::string> name; + +	Name() +	:	name("name") +	{} +}; + +struct Attribute : public LLInitParam::Block<Attribute> +{ +	Mandatory<Name>			name; +	Mandatory<std::string>	type; +	Mandatory<EUse>			use; +	 +	Attribute() +	:	name("name"), +		type("type"), +		use("use") +	{ +	} +}; + +struct ComplexType : public LLInitParam::Block<ComplexType> +{ +	Multiple<Attribute>			attribute; +	//Multiple<struct Element>	elements; +	Optional<bool>				mixed; + +	ComplexType() +	:	attribute("xs:attribute"), +		//elements("xs:element"), +		mixed("mixed") +	{ +		mixed = true; +	} +}; + +struct Element : public LLInitParam::Block<Element, Occurs> +{ +	Mandatory<ComplexType>	complexType; +	Mandatory<Name>			name; + +	Element() +	:	complexType("xs:complexType") +	{} +}; + +struct Elements : public LLInitParam::Block<Elements, Occurs> +{ +	Multiple<Element> elements; + +	Elements() +	:	elements("xs:element") +	{} +}; + +struct Schema : public LLInitParam::Block<Schema> +{ +private: +	Mandatory<std::string>	targetNamespace, +							xmlns; + +public: +	Optional<std::string>	attributeFormDefault, +							elementFormDefault, +							xs; + +	Optional<Elements>		elements; +	 +	void setNameSpace(const std::string& ns) {targetNamespace = ns; xmlns = ns;} + +	Schema() +	:	attributeFormDefault("attributeFormDefault"), +		elementFormDefault("elementFormDefault"), +		xs("xmlns:xs"), +		targetNamespace("targetNamespace"), +		xmlns("xmlns"), +		elements("xs:choice") +	{ +		attributeFormDefault = "unqualified"; +		elementFormDefault = "qualified"; +		xs = "http://www.w3.org/2001/XMLSchema"; +	} + +};  //  // LLXSDWriter @@ -383,12 +513,11 @@ static 	LLInitParam::Parser::parser_inspect_func_map_t sXUIInspectFuncs;  //  LLXUIParser::LLXUIParser()  :	Parser(sXUIReadFuncs, sXUIWriteFuncs, sXUIInspectFuncs), -	mLastWriteGeneration(-1),  	mCurReadDepth(0)  {  	if (sXUIReadFuncs.empty())  	{ -		registerParserFuncs<LLInitParam::NoParamValue>(readNoValue, writeNoValue); +		registerParserFuncs<LLInitParam::Flag>(readFlag, writeFlag);  		registerParserFuncs<bool>(readBoolValue, writeBoolValue);  		registerParserFuncs<std::string>(readStringValue, writeStringValue);  		registerParserFuncs<U8>(readU8Value, writeU8Value); @@ -453,7 +582,7 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block)  	if (!text_contents.empty())  	{  		mCurReadNode = nodep; -		mNameStack.push_back(std::make_pair(std::string("value"), newParseGeneration())); +		mNameStack.push_back(std::make_pair(std::string("value"), true));  		// child nodes are not necessarily valid parameters (could be a child widget)  		// so don't complain once we've recursed  		if (!block.submitValue(mNameStack, *this, true)) @@ -488,7 +617,7 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block)  		// since there is no widget named "rect"  		if (child_name.find(".") == std::string::npos)   		{ -			mNameStack.push_back(std::make_pair(child_name, newParseGeneration())); +			mNameStack.push_back(std::make_pair(child_name, true));  			num_tokens_pushed++;  		}  		else @@ -524,7 +653,7 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block)  			// copy remaining tokens on to our running token list  			for(tokenizer::iterator token_to_push = name_token_it; token_to_push != name_tokens.end(); ++token_to_push)  			{ -				mNameStack.push_back(std::make_pair(*token_to_push, newParseGeneration())); +				mNameStack.push_back(std::make_pair(*token_to_push, true));  				num_tokens_pushed++;  			}  		} @@ -574,7 +703,7 @@ bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& blo  		// copy remaining tokens on to our running token list  		for(tokenizer::iterator token_to_push = name_tokens.begin(); token_to_push != name_tokens.end(); ++token_to_push)  		{ -			mNameStack.push_back(std::make_pair(*token_to_push, newParseGeneration())); +			mNameStack.push_back(std::make_pair(*token_to_push, true));  			num_tokens_pushed++;  		} @@ -593,48 +722,40 @@ bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& blo  void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::BaseBlock* diff_block)  {  	mWriteRootNode = node; -	block.serializeBlock(*this, Parser::name_stack_t(), diff_block); +	name_stack_t name_stack = Parser::name_stack_t(); +	block.serializeBlock(*this, name_stack, diff_block);  	mOutNodes.clear();  }  // go from a stack of names to a specific XML node -LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack) +LLXMLNodePtr LLXUIParser::getNode(name_stack_t& stack)  { -	name_stack_t name_stack; -	for (name_stack_t::const_iterator it = stack.begin(); -		it != stack.end(); -		++it) -	{ -		if (!it->first.empty()) -		{ -			name_stack.push_back(*it); -		} -	} -  	LLXMLNodePtr out_node = mWriteRootNode; -	name_stack_t::const_iterator next_it = name_stack.begin(); -	for (name_stack_t::const_iterator it = name_stack.begin(); -		it != name_stack.end(); +	name_stack_t::iterator next_it = stack.begin(); +	for (name_stack_t::iterator it = stack.begin(); +		it != stack.end();  		it = next_it)  	{  		++next_it;  		if (it->first.empty())  		{ +			it->second = false;  			continue;  		} -		out_nodes_t::iterator found_it = mOutNodes.lower_bound(it->second); +		out_nodes_t::iterator found_it = mOutNodes.find(it->first);  		// node with this name not yet written -		if (found_it == mOutNodes.end() || mOutNodes.key_comp()(found_it->first, it->second)) +		if (found_it == mOutNodes.end() || it->second)  		{  			// make an attribute if we are the last element on the name stack -			bool is_attribute = next_it == name_stack.end(); +			bool is_attribute = next_it == stack.end();  			LLXMLNodePtr new_node = new LLXMLNode(it->first.c_str(), is_attribute);  			out_node->addChild(new_node); -			mOutNodes.insert(found_it, std::make_pair(it->second, new_node)); +			mOutNodes[it->first] = new_node;  			out_node = new_node; +			it->second = false;  		}  		else  		{ @@ -645,13 +766,13 @@ LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack)  	return (out_node == mWriteRootNode ? LLXMLNodePtr(NULL) : out_node);  } -bool LLXUIParser::readNoValue(Parser& parser, void* val_ptr) +bool LLXUIParser::readFlag(Parser& parser, void* val_ptr)  {  	LLXUIParser& self = static_cast<LLXUIParser&>(parser);  	return self.mCurReadNode == DUMMY_NODE;  } -bool LLXUIParser::writeNoValue(Parser& parser, const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeFlag(Parser& parser, const void* val_ptr, name_stack_t& stack)  {  	// just create node  	LLXUIParser& self = static_cast<LLXUIParser&>(parser); @@ -668,7 +789,7 @@ bool LLXUIParser::readBoolValue(Parser& parser, void* val_ptr)  	return success;  } -bool LLXUIParser::writeBoolValue(Parser& parser, const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeBoolValue(Parser& parser, const void* val_ptr, name_stack_t& stack)  {  	LLXUIParser& self = static_cast<LLXUIParser&>(parser);  	LLXMLNodePtr node = self.getNode(stack); @@ -687,7 +808,7 @@ bool LLXUIParser::readStringValue(Parser& parser, void* val_ptr)  	return true;  } -bool LLXUIParser::writeStringValue(Parser& parser, const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeStringValue(Parser& parser, const void* val_ptr, name_stack_t& stack)  {  	LLXUIParser& self = static_cast<LLXUIParser&>(parser);  	LLXMLNodePtr node = self.getNode(stack); @@ -725,7 +846,7 @@ bool LLXUIParser::readU8Value(Parser& parser, void* val_ptr)  	return self.mCurReadNode->getByteValue(1, (U8*)val_ptr);  } -bool LLXUIParser::writeU8Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeU8Value(Parser& parser, const void* val_ptr, name_stack_t& stack)  {  	LLXUIParser& self = static_cast<LLXUIParser&>(parser);  	LLXMLNodePtr node = self.getNode(stack); @@ -749,7 +870,7 @@ bool LLXUIParser::readS8Value(Parser& parser, void* val_ptr)  	return false;  } -bool LLXUIParser::writeS8Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeS8Value(Parser& parser, const void* val_ptr, name_stack_t& stack)  {  	LLXUIParser& self = static_cast<LLXUIParser&>(parser);  	LLXMLNodePtr node = self.getNode(stack); @@ -773,7 +894,7 @@ bool LLXUIParser::readU16Value(Parser& parser, void* val_ptr)  	return false;  } -bool LLXUIParser::writeU16Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeU16Value(Parser& parser, const void* val_ptr, name_stack_t& stack)  {  	LLXUIParser& self = static_cast<LLXUIParser&>(parser);  	LLXMLNodePtr node = self.getNode(stack); @@ -797,7 +918,7 @@ bool LLXUIParser::readS16Value(Parser& parser, void* val_ptr)  	return false;  } -bool LLXUIParser::writeS16Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeS16Value(Parser& parser, const void* val_ptr, name_stack_t& stack)  {  	LLXUIParser& self = static_cast<LLXUIParser&>(parser);  	LLXMLNodePtr node = self.getNode(stack); @@ -815,7 +936,7 @@ bool LLXUIParser::readU32Value(Parser& parser, void* val_ptr)  	return self.mCurReadNode->getUnsignedValue(1, (U32*)val_ptr);  } -bool LLXUIParser::writeU32Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeU32Value(Parser& parser, const void* val_ptr, name_stack_t& stack)  {  	LLXUIParser& self = static_cast<LLXUIParser&>(parser);  	LLXMLNodePtr node = self.getNode(stack); @@ -833,7 +954,7 @@ bool LLXUIParser::readS32Value(Parser& parser, void* val_ptr)  	return self.mCurReadNode->getIntValue(1, (S32*)val_ptr);  } -bool LLXUIParser::writeS32Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeS32Value(Parser& parser, const void* val_ptr, name_stack_t& stack)  {  	LLXUIParser& self = static_cast<LLXUIParser&>(parser);  	LLXMLNodePtr node = self.getNode(stack); @@ -851,7 +972,7 @@ bool LLXUIParser::readF32Value(Parser& parser, void* val_ptr)  	return self.mCurReadNode->getFloatValue(1, (F32*)val_ptr);  } -bool LLXUIParser::writeF32Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeF32Value(Parser& parser, const void* val_ptr, name_stack_t& stack)  {  	LLXUIParser& self = static_cast<LLXUIParser&>(parser);  	LLXMLNodePtr node = self.getNode(stack); @@ -869,7 +990,7 @@ bool LLXUIParser::readF64Value(Parser& parser, void* val_ptr)  	return self.mCurReadNode->getDoubleValue(1, (F64*)val_ptr);  } -bool LLXUIParser::writeF64Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeF64Value(Parser& parser, const void* val_ptr, name_stack_t& stack)  {  	LLXUIParser& self = static_cast<LLXUIParser&>(parser);  	LLXMLNodePtr node = self.getNode(stack); @@ -893,7 +1014,7 @@ bool LLXUIParser::readColor4Value(Parser& parser, void* val_ptr)  	return false;  } -bool LLXUIParser::writeColor4Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeColor4Value(Parser& parser, const void* val_ptr, name_stack_t& stack)  {  	LLXUIParser& self = static_cast<LLXUIParser&>(parser);  	LLXMLNodePtr node = self.getNode(stack); @@ -920,7 +1041,7 @@ bool LLXUIParser::readUIColorValue(Parser& parser, void* val_ptr)  	return false;  } -bool LLXUIParser::writeUIColorValue(Parser& parser, const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeUIColorValue(Parser& parser, const void* val_ptr, name_stack_t& stack)  {  	LLXUIParser& self = static_cast<LLXUIParser&>(parser);  	LLXMLNodePtr node = self.getNode(stack); @@ -949,7 +1070,7 @@ bool LLXUIParser::readUUIDValue(Parser& parser, void* val_ptr)  	return false;  } -bool LLXUIParser::writeUUIDValue(Parser& parser, const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeUUIDValue(Parser& parser, const void* val_ptr, name_stack_t& stack)  {  	LLXUIParser& self = static_cast<LLXUIParser&>(parser);  	LLXMLNodePtr node = self.getNode(stack); @@ -968,7 +1089,7 @@ bool LLXUIParser::readSDValue(Parser& parser, void* val_ptr)  	return true;  } -bool LLXUIParser::writeSDValue(Parser& parser, const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeSDValue(Parser& parser, const void* val_ptr, name_stack_t& stack)  {  	LLXUIParser& self = static_cast<LLXUIParser&>(parser); @@ -1077,13 +1198,12 @@ const char* NO_VALUE_MARKER = "no_value";  LLSimpleXUIParser::LLSimpleXUIParser(LLSimpleXUIParser::element_start_callback_t element_cb)  :	Parser(sSimpleXUIReadFuncs, sSimpleXUIWriteFuncs, sSimpleXUIInspectFuncs), -	mLastWriteGeneration(-1),  	mCurReadDepth(0),  	mElementCB(element_cb)  {  	if (sSimpleXUIReadFuncs.empty())  	{ -		registerParserFuncs<LLInitParam::NoParamValue>(readNoValue); +		registerParserFuncs<LLInitParam::Flag>(readFlag);  		registerParserFuncs<bool>(readBoolValue);  		registerParserFuncs<std::string>(readStringValue);  		registerParserFuncs<U8>(readU8Value); @@ -1208,7 +1328,7 @@ void LLSimpleXUIParser::startElement(const char *name, const char **atts)  	{	// compound attribute  		if (child_name.find(".") == std::string::npos)   		{ -			mNameStack.push_back(std::make_pair(child_name, newParseGeneration())); +			mNameStack.push_back(std::make_pair(child_name, true));  			num_tokens_pushed++;  			mScope.push_back(child_name);  		} @@ -1235,7 +1355,7 @@ void LLSimpleXUIParser::startElement(const char *name, const char **atts)  			// copy remaining tokens on to our running token list  			for(tokenizer::iterator token_to_push = name_token_it; token_to_push != name_tokens.end(); ++token_to_push)  			{ -				mNameStack.push_back(std::make_pair(*token_to_push, newParseGeneration())); +				mNameStack.push_back(std::make_pair(*token_to_push, true));  				num_tokens_pushed++;  			}  			mScope.push_back(mNameStack.back().first); @@ -1268,7 +1388,7 @@ bool LLSimpleXUIParser::readAttributes(const char **atts)  		// copy remaining tokens on to our running token list  		for(tokenizer::iterator token_to_push = name_tokens.begin(); token_to_push != name_tokens.end(); ++token_to_push)  		{ -			mNameStack.push_back(std::make_pair(*token_to_push, newParseGeneration())); +			mNameStack.push_back(std::make_pair(*token_to_push, true));  			num_tokens_pushed++;  		} @@ -1290,7 +1410,7 @@ bool LLSimpleXUIParser::processText()  		LLStringUtil::trim(mTextContents);  		if (!mTextContents.empty())  		{ -			mNameStack.push_back(std::make_pair(std::string("value"), newParseGeneration())); +			mNameStack.push_back(std::make_pair(std::string("value"), true));  			mCurAttributeValueBegin = mTextContents.c_str();  			mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently);  			mNameStack.pop_back(); @@ -1376,7 +1496,7 @@ void LLSimpleXUIParser::parserError(const std::string& message)  #endif  } -bool LLSimpleXUIParser::readNoValue(Parser& parser, void* val_ptr) +bool LLSimpleXUIParser::readFlag(Parser& parser, void* val_ptr)  {  	LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);  	return self.mCurAttributeValueBegin == NO_VALUE_MARKER; diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h index 0c38c4da93..d7cd256967 100644 --- a/indra/llxuixml/llxuiparser.h +++ b/indra/llxuixml/llxuiparser.h @@ -116,7 +116,7 @@ private:  	bool readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block);  	//reader helper functions -	static bool readNoValue(Parser& parser, void* val_ptr); +	static bool readFlag(Parser& parser, void* val_ptr);  	static bool readBoolValue(Parser& parser, void* val_ptr);  	static bool readStringValue(Parser& parser, void* val_ptr);  	static bool readU8Value(Parser& parser, void* val_ptr); @@ -133,23 +133,23 @@ private:  	static bool readSDValue(Parser& parser, void* val_ptr);  	//writer helper functions -	static bool writeNoValue(Parser& parser, const void* val_ptr, const name_stack_t&); -	static bool writeBoolValue(Parser& parser, const void* val_ptr, const name_stack_t&); -	static bool writeStringValue(Parser& parser, const void* val_ptr, const name_stack_t&); -	static bool writeU8Value(Parser& parser, const void* val_ptr, const name_stack_t&); -	static bool writeS8Value(Parser& parser, const void* val_ptr, const name_stack_t&); -	static bool writeU16Value(Parser& parser, const void* val_ptr, const name_stack_t&); -	static bool writeS16Value(Parser& parser, const void* val_ptr, const name_stack_t&); -	static bool writeU32Value(Parser& parser, const void* val_ptr, const name_stack_t&); -	static bool writeS32Value(Parser& parser, const void* val_ptr, const name_stack_t&); -	static bool writeF32Value(Parser& parser, const void* val_ptr, const name_stack_t&); -	static bool writeF64Value(Parser& parser, const void* val_ptr, const name_stack_t&); -	static bool writeColor4Value(Parser& parser, const void* val_ptr, const name_stack_t&); -	static bool writeUIColorValue(Parser& parser, const void* val_ptr, const name_stack_t&); -	static bool writeUUIDValue(Parser& parser, const void* val_ptr, const name_stack_t&); -	static bool writeSDValue(Parser& parser, const void* val_ptr, const name_stack_t&); - -	LLXMLNodePtr getNode(const name_stack_t& stack); +	static bool writeFlag(Parser& parser, const void* val_ptr, name_stack_t&); +	static bool writeBoolValue(Parser& parser, const void* val_ptr, name_stack_t&); +	static bool writeStringValue(Parser& parser, const void* val_ptr, name_stack_t&); +	static bool writeU8Value(Parser& parser, const void* val_ptr, name_stack_t&); +	static bool writeS8Value(Parser& parser, const void* val_ptr, name_stack_t&); +	static bool writeU16Value(Parser& parser, const void* val_ptr, name_stack_t&); +	static bool writeS16Value(Parser& parser, const void* val_ptr, name_stack_t&); +	static bool writeU32Value(Parser& parser, const void* val_ptr, name_stack_t&); +	static bool writeS32Value(Parser& parser, const void* val_ptr, name_stack_t&); +	static bool writeF32Value(Parser& parser, const void* val_ptr, name_stack_t&); +	static bool writeF64Value(Parser& parser, const void* val_ptr, name_stack_t&); +	static bool writeColor4Value(Parser& parser, const void* val_ptr, name_stack_t&); +	static bool writeUIColorValue(Parser& parser, const void* val_ptr, name_stack_t&); +	static bool writeUUIDValue(Parser& parser, const void* val_ptr, name_stack_t&); +	static bool writeSDValue(Parser& parser, const void* val_ptr, name_stack_t&); + +	LLXMLNodePtr getNode(name_stack_t& stack);  private:  	Parser::name_stack_t			mNameStack; @@ -157,9 +157,8 @@ private:  	// Root of the widget XML sub-tree, for example, "line_editor"  	LLXMLNodePtr					mWriteRootNode; -	typedef std::map<S32, LLXMLNodePtr>	out_nodes_t; +	typedef std::map<std::string, LLXMLNodePtr>	out_nodes_t;  	out_nodes_t						mOutNodes; -	S32								mLastWriteGeneration;  	LLXMLNodePtr					mLastWrittenChild;  	S32								mCurReadDepth;  	std::string						mCurFileName; @@ -197,7 +196,7 @@ public:  private:  	//reader helper functions -	static bool readNoValue(Parser&, void* val_ptr); +	static bool readFlag(Parser&, void* val_ptr);  	static bool readBoolValue(Parser&, void* val_ptr);  	static bool readStringValue(Parser&, void* val_ptr);  	static bool readU8Value(Parser&, void* val_ptr); @@ -226,7 +225,6 @@ private:  	Parser::name_stack_t			mNameStack;  	struct XML_ParserStruct*		mParser; -	S32								mLastWriteGeneration;  	LLXMLNodePtr					mLastWrittenChild;  	S32								mCurReadDepth;  	std::string						mCurFileName; | 
