예제 #1
0
	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const
	{
		// named param is one like LLView::Params::follows
		// unnamed param is like LLView::Params::rect - implicit
		const BlockDescriptor& block_data = mostDerivedBlockDescriptor();

		for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin(); 
			it != block_data.mUnnamedParams.end(); 
			++it)
		{
			param_handle_t param_handle = (*it)->mParamHandle;
			const Param* param = getParamFromHandle(param_handle);
			ParamDescriptor::inspect_func_t inspect_func = (*it)->mInspectFunc;
			if (inspect_func)
			{
				(*it)->mGeneration = parser.newParseGeneration();
				name_stack.push_back(std::make_pair("", (*it)->mGeneration));
				inspect_func(*param, parser, name_stack, (*it)->mMinCount, (*it)->mMaxCount);
				name_stack.pop_back();
			}
		}

		for(BlockDescriptor::param_map_t::const_iterator it = block_data.mNamedParams.begin();
			it != block_data.mNamedParams.end();
			++it)
		{
			param_handle_t param_handle = it->second->mParamHandle;
			const Param* param = getParamFromHandle(param_handle);
			ParamDescriptor::inspect_func_t inspect_func = it->second->mInspectFunc;
			if (inspect_func)
			{
				// Ensure this param has not already been inspected
				bool duplicate = false;
				for (BlockDescriptor::param_list_t::const_iterator it2 = block_data.mUnnamedParams.begin(); 
					it2 != block_data.mUnnamedParams.end(); 
					++it2)
				{
					if (param_handle == (*it2)->mParamHandle)
					{
						duplicate = true;
						break;
					}
				}

				if (!duplicate)
				{
					it->second->mGeneration = parser.newParseGeneration();
				}
				name_stack.push_back(std::make_pair(it->first, it->second->mGeneration));
				inspect_func(*param, parser, name_stack, it->second->mMinCount, it->second->mMaxCount);
				name_stack.pop_back();
			}
		}

		return true;
	}
예제 #2
0
	bool BaseBlock::submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent)
	{
		if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end())))
		{
			if (!silent)
			{
				p.parserWarning(llformat("Failed to parse parameter \"%s\"", p.getCurrentElementName().c_str()));
			}
			return false;
		}
		return true;
	}
예제 #3
0
void LLRNGWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values)
{
	if (max_count == 0) return;

	name_stack_t non_empty_names;
	std::string attribute_name;
	for (name_stack_t::const_iterator it = stack.begin();
		it != stack.end();
		++it)
	{
		const std::string& name = it->first;
		if (!name.empty())
		{
			non_empty_names.push_back(*it);
		}
	}

	if (non_empty_names.empty()) return;

	for (name_stack_t::const_iterator it = non_empty_names.begin();
		it != non_empty_names.end();
		++it)
	{
		if (!attribute_name.empty())
		{
			attribute_name += ".";
		}
		attribute_name += it->first;
	}

	// singular attribute, e.g. <foo bar="1"/>
	if (non_empty_names.size() == 1 && max_count == 1)
	{
		if (mAttributesWritten.second.find(attribute_name) == mAttributesWritten.second.end())
		{
			LLXMLNodePtr node = createCardinalityNode(mElementNode, min_count, max_count)->createChild("attribute", false);
			node->createChild("name", true)->setStringValue(attribute_name);
			node->createChild("data", false)->createChild("type", true)->setStringValue(type);

			mAttributesWritten.second.insert(attribute_name);
		}
	}
	// compound attribute
	else
	{
		std::string element_name;

		// traverse all but last element, leaving that as an attribute name
		name_stack_t::const_iterator end_it = non_empty_names.end();
		end_it--;

		for (name_stack_t::const_iterator it = non_empty_names.begin();
			it != end_it;
			++it)
		{
			if (it != non_empty_names.begin())
			{
				element_name += ".";
			}
			element_name += it->first;
		}

		elements_map_t::iterator found_it = mElementsWritten.find(element_name);
		// <choice>
		//   <group>
		//     <optional>
		//	     <attribute name="foo.bar"><data type="string"/></attribute>
		//     </optional>
		//     <optional>
		//       <attribute name="foo.baz"><data type="integer"/></attribute>
		//     </optional>
		//   </group>
		//   <element name="foo">
		//     <optional>
		//       <attribute name="bar"><data type="string"/></attribute>
		//     </optional>
		//     <optional>
		//       <attribute name="baz"><data type="string"/></attribute>
		//     </optional>
		//   </element>
		//   <element name="outer.foo">
		//     <ref name="foo"/>
		//   </element>
		// </choice>

		if (found_it != mElementsWritten.end())
		{
			// reuse existing element
			LLXMLNodePtr choice_node = found_it->second.first;

			// attribute with this name not already written?
			if (found_it->second.second.find(attribute_name) == found_it->second.second.end())
			{
				// append to <group>
				LLXMLNodePtr node = choice_node->mChildren->head;
				node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
				node->createChild("name", true)->setStringValue(attribute_name);
				addTypeNode(node, type, possible_values);

				// append to <element>
				node = choice_node->mChildren->head->mNext->mChildren->head;
				node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
				node->createChild("name", true)->setStringValue(non_empty_names.back().first);
				addTypeNode(node, type, possible_values);

				// append to <element>
				//node = choice_node->mChildren->head->mNext->mNext->mChildren->head;
				//node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
				//node->createChild("name", true)->setStringValue(non_empty_names.back().first);
				//addTypeNode(node, type, possible_values);

				found_it->second.second.insert(attribute_name);
			}
		}
		else
		{
			LLXMLNodePtr choice_node = mElementNode->createChild("choice", false);

			LLXMLNodePtr node = choice_node->createChild("group", false);
			node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
			node->createChild("name", true)->setStringValue(attribute_name);
			addTypeNode(node, type, possible_values);

			node = choice_node->createChild("optional", false);
			node = node->createChild("element", false);
			node->createChild("name", true)->setStringValue(element_name);
			node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
			node->createChild("name", true)->setStringValue(non_empty_names.back().first);
			addTypeNode(node, type, possible_values);
			
			//node = choice_node->createChild("optional", false);
			//node = node->createChild("element", false);
			//node->createChild("name", true)->setStringValue(mDefinitionName + "." + element_name);
			//node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false);
			//node->createChild("name", true)->setStringValue(non_empty_names.back().first);
			//addTypeNode(node, type, possible_values);

			attribute_data_t& attribute_data = mElementsWritten[element_name];
			attribute_data.first = choice_node;
			attribute_data.second.insert(attribute_name);
		}
	}
}
예제 #4
0
	bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const
	{
		// named param is one like LLView::Params::follows
		// unnamed param is like LLView::Params::rect - implicit
		const BlockDescriptor& block_data = mostDerivedBlockDescriptor();

		for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin(); 
			it != block_data.mUnnamedParams.end(); 
			++it)
		{
			param_handle_t param_handle = (*it)->mParamHandle;
			const Param* param = getParamFromHandle(param_handle);
			ParamDescriptor::serialize_func_t serialize_func = (*it)->mSerializeFunc;
			if (serialize_func)
			{
				const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
				// 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));
				serialize_func(*param, parser, name_stack, diff_param);
				name_stack.pop_back();
			}
		}

		for(BlockDescriptor::param_map_t::const_iterator it = block_data.mNamedParams.begin();
			it != block_data.mNamedParams.end();
			++it)
		{
			param_handle_t param_handle = it->second->mParamHandle;
			const Param* param = getParamFromHandle(param_handle);
			ParamDescriptor::serialize_func_t serialize_func = it->second->mSerializeFunc;
			if (serialize_func && param->anyProvided())
			{
				// Ensure this param has not already been serialized
				// Prevents <rect> from being serialized as its own tag.
				bool duplicate = false;
				for (BlockDescriptor::param_list_t::const_iterator it2 = block_data.mUnnamedParams.begin(); 
					it2 != block_data.mUnnamedParams.end(); 
					++it2)
				{
					if (param_handle == (*it2)->mParamHandle)
					{
						duplicate = true;
						break;
					}
				}

				//FIXME: for now, don't attempt to serialize values under synonyms, as current parsers
				// don't know how to detect them
				if (duplicate) 
				{
					continue;
				}

				if (!duplicate)
				{
					it->second->mGeneration = parser.newParseGeneration();
				}

				name_stack.push_back(std::make_pair(it->first, it->second->mGeneration));
				const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
				serialize_func(*param, parser, name_stack, diff_param);
				name_stack.pop_back();
			}
		}

		return true;
	}
예제 #5
0
void LLXSDWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values)
{
	name_stack_t non_empty_names;
	std::string attribute_name;
	for (name_stack_t::const_iterator it = stack.begin();
		it != stack.end();
		++it)
	{
		const std::string& name = it->first;
		if (!name.empty())
		{
			non_empty_names.push_back(*it);
		}
	}

	for (name_stack_t::const_iterator it = non_empty_names.begin();
		it != non_empty_names.end();
		++it)
	{
		if (!attribute_name.empty())
		{
			attribute_name += ".";
		}
		attribute_name += it->first;
	}

	// only flag non-nested attributes as mandatory, nested attributes have variant syntax
	// that can't be properly constrained in XSD
	// e.g. <foo mandatory.value="bar"/> vs <foo><mandatory value="bar"/></foo>
	bool attribute_mandatory = min_count == 1 && max_count == 1 && non_empty_names.size() == 1;

	// don't bother supporting "Multiple" params as xml attributes
	if (max_count <= 1)
	{
		// add compound attribute to root node
		addAttributeToSchema(mAttributeNode, attribute_name, type, attribute_mandatory, possible_values);
	}

	// now generated nested elements for compound attributes
	if (non_empty_names.size() > 1 && !attribute_mandatory)
	{
		std::string element_name;

		// traverse all but last element, leaving that as an attribute name
		name_stack_t::const_iterator end_it = non_empty_names.end();
		end_it--;

		for (name_stack_t::const_iterator it = non_empty_names.begin();
			it != end_it;
			++it)
		{
			if (it != non_empty_names.begin())
			{
				element_name += ".";
			}
			element_name += it->first;
		}

		std::string short_attribute_name = non_empty_names.back().first;

		LLXMLNodePtr complex_type_node;

		// find existing element node here, starting at tail of child list
		if (mElementNode->mChildren.notNull())
		{
			for(LLXMLNodePtr element = mElementNode->mChildren->tail;
				element.notNull(); 
				element = element->mPrev)
			{
				std::string name;
				if(element->getAttributeString("name", name) && name == element_name)
				{
					complex_type_node = element->mChildren->head;
					break;
				}
			}
		}
		//create complex_type node
		//
		//<xs:element
        //    maxOccurs="1"
        //    minOccurs="0"
        //    name="name">
        //       <xs:complexType>
        //       </xs:complexType>
        //</xs:element>
		if(complex_type_node.isNull())
		{
			complex_type_node = mElementNode->createChild("xs:element", false);

			complex_type_node->createChild("minOccurs", true)->setIntValue(min_count);
			complex_type_node->createChild("maxOccurs", true)->setIntValue(max_count);
			complex_type_node->createChild("name",		true)->setStringValue(element_name);
			complex_type_node = complex_type_node->createChild("xs:complexType", false);
		}

		addAttributeToSchema(complex_type_node, short_attribute_name, type, false, possible_values);
	}
}