bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block) { typedef boost::tokenizer<boost::char_separator<char> > tokenizer; boost::char_separator<char> sep("."); bool any_parsed = false; for(LLXMLAttribList::const_iterator attribute_it = nodep->mAttributes.begin(); attribute_it != nodep->mAttributes.end(); ++attribute_it) { S32 num_tokens_pushed = 0; std::string attribute_name(attribute_it->first->mString); mCurReadNode = attribute_it->second; tokenizer name_tokens(attribute_name, sep); // 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())); num_tokens_pushed++; } // child nodes are not necessarily valid attributes, so don't complain once we've recursed bool silent = mCurReadDepth > 0; any_parsed |= block.submitValue(mNameStack, *this, silent); while(num_tokens_pushed-- > 0) { mNameStack.pop_back(); } } return any_parsed; }
void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block) { mNameStack.clear(); mWriteRootSD = &sd; name_stack_t name_stack; block.serializeBlock(*this, name_stack); }
void LLParamSDParser::writeSDImpl(LLSD& sd, const LLInitParam::BaseBlock& block, const LLInitParam::predicate_rule_t rules, const LLInitParam::BaseBlock* diff_block) { mNameStack.clear(); mWriteRootSD = &sd; name_stack_t name_stack; block.serializeBlock(*this, name_stack, rules, diff_block); }
void LLRNGWriter::addDefinition(const std::string& type_name, const LLInitParam::BaseBlock& block) { if (mDefinedElements.find(type_name) != mDefinedElements.end()) return; mDefinedElements.insert(type_name); LLXMLNodePtr node = mGrammarNode->createChild("define", false); node->createChild("name", true)->setStringValue(type_name); mElementNode = node->createChild("element", false); mElementNode->createChild("name", true)->setStringValue(type_name); mChildrenNode = mElementNode->createChild("zeroOrMore", false)->createChild("choice", false); mAttributesWritten.first = mElementNode; mAttributesWritten.second.clear(); mElementsWritten.clear(); block.inspectBlock(*this); // add includes for all possible children const std::type_info* type = *LLWidgetTypeRegistry::instance().getValue(type_name); const widget_registry_t* widget_registryp = LLChildRegistryRegistry::instance().getValue(type); // add include declarations for all valid children for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems(); it != widget_registryp->currentRegistrar().endItems(); ++it) { std::string child_name = it->first; if (child_name == type_name) { continue; } LLXMLNodePtr old_element_node = mElementNode; LLXMLNodePtr old_child_node = mChildrenNode; //FIXME: add LLDefaultParamBlockRegistry back when working on schema generation //addDefinition(child_name, (*LLDefaultParamBlockRegistry::instance().getValue(type))()); mElementNode = old_element_node; mChildrenNode = old_child_node; mChildrenNode->createChild("ref", false)->createChild("name", true)->setStringValue(child_name); } if (mChildrenNode->mChildren.isNull()) { // remove unused children node mChildrenNode->mParent->mParent->deleteChild(mChildrenNode->mParent); } }
void LLXSDWriter::writeXSD(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace) { 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"); block.inspectBlock(*this); // duplicate element choices LLXMLNodeList children; mElementNode->getChildren("xs:element", children, FALSE); for (LLXMLNodeList::iterator child_it = children.begin(); child_it != children.end(); ++child_it) { LLXMLNodePtr child_copy = child_it->second->deepCopy(); std::string child_name; child_copy->getAttributeString("name", child_name); child_copy->setAttributeString("name", type_name + "." + child_name); mElementNode->addChild(child_copy); } LLXMLNodePtr element_declaration_node = mSchemaNode->createChild("xs:element", false); element_declaration_node->createChild("name", true)->setStringValue(type_name); element_declaration_node->createChild("type", true)->setStringValue(type_name); }
void LLParamSDParser::submit(LLInitParam::BaseBlock& block, const LLSD& sd, LLInitParam::Parser::name_stack_t& name_stack) { mCurReadSD = &sd; block.submitValue(name_stack, *this); }
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); mOutNodes.clear(); }
bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLInitParam::BaseBlock& block) { typedef boost::tokenizer<boost::char_separator<char> > tokenizer; boost::char_separator<char> sep("."); bool values_parsed = false; // submit attributes for current node values_parsed |= readAttributes(nodep, block); // treat text contents of xml node as "value" parameter std::string text_contents = nodep->getSanitizedValue(); if (!text_contents.empty()) { mCurReadNode = nodep; mNameStack.push_back(std::make_pair(std::string("value"), newParseGeneration())); // child nodes are not necessarily valid parameters (could be a child widget) // so don't complain once we've recursed bool silent = mCurReadDepth > 0; if (!block.submitValue(mNameStack, *this, true)) { mNameStack.pop_back(); block.submitValue(mNameStack, *this, silent); } else { mNameStack.pop_back(); } } // then traverse children // child node must start with last name of parent node (our "scope") // for example: "<button><button.param nested_param1="foo"><param.nested_param2 nested_param3="bar"/></button.param></button>" // which equates to the following nesting: // button // param // nested_param1 // nested_param2 // nested_param3 mCurReadDepth++; for(LLXMLNodePtr childp = nodep->getFirstChild(); childp.notNull();) { std::string child_name(childp->getName()->mString); S32 num_tokens_pushed = 0; // for non "dotted" child nodes check to see if child node maps to another widget type // and if not, treat as a child element of the current node // e.g. <button><rect left="10"/></button> will interpret <rect> as "button.rect" // since there is no widget named "rect" if (child_name.find(".") == std::string::npos) { mNameStack.push_back(std::make_pair(child_name, newParseGeneration())); num_tokens_pushed++; } else { // parse out "dotted" name into individual tokens tokenizer name_tokens(child_name, sep); tokenizer::iterator name_token_it = name_tokens.begin(); if(name_token_it == name_tokens.end()) { childp = childp->getNextSibling(); continue; } // check for proper nesting if(!scope.empty() && *name_token_it != scope) { childp = childp->getNextSibling(); continue; } // now ignore first token ++name_token_it; // 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())); num_tokens_pushed++; } } // recurse and visit children XML nodes if(readXUIImpl(childp, mNameStack.empty() ? scope : mNameStack.back().first, block)) { // child node successfully parsed, remove from DOM values_parsed = true; LLXMLNodePtr node_to_remove = childp; childp = childp->getNextSibling(); nodep->deleteChild(node_to_remove); } else { childp = childp->getNextSibling(); } while(num_tokens_pushed-- > 0) { mNameStack.pop_back(); } } mCurReadDepth--; return values_parsed; }