diff options
Diffstat (limited to 'indra/llxuixml/llxuiparser.cpp')
-rw-r--r-- | indra/llxuixml/llxuiparser.cpp | 307 |
1 files changed, 213 insertions, 94 deletions
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index 4af077b22c..878f992178 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -51,6 +51,144 @@ 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; +static LLInitParam::Parser::parser_read_func_map_t sSimpleXUIReadFuncs; +static LLInitParam::Parser::parser_write_func_map_t sSimpleXUIWriteFuncs; +static LLInitParam::Parser::parser_inspect_func_map_t sSimpleXUIInspectFuncs; + +const char* NO_VALUE_MARKER = "no_value"; + +const S32 LINE_NUMBER_HERE = 0; + +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 +521,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 +590,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 +625,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 +661,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 +711,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 +730,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 +774,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 +797,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 +816,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 +854,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 +878,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 +902,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 +926,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 +944,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 +962,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 +980,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 +998,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 +1022,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 +1049,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 +1078,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 +1097,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); @@ -1069,21 +1198,14 @@ struct ScopedFile LLFILE* mFile; }; -static LLInitParam::Parser::parser_read_func_map_t sSimpleXUIReadFuncs; -static LLInitParam::Parser::parser_write_func_map_t sSimpleXUIWriteFuncs; -static LLInitParam::Parser::parser_inspect_func_map_t sSimpleXUIInspectFuncs; - -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); @@ -1180,6 +1302,11 @@ void LLSimpleXUIParser::characterDataHandler(void *userData, const char *s, int self->characterData(s, len); } +void LLSimpleXUIParser::characterData(const char *s, int len) +{ + mTextContents += std::string(s, len); +} + void LLSimpleXUIParser::startElement(const char *name, const char **atts) { processText(); @@ -1208,7 +1335,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 +1362,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); @@ -1252,6 +1379,37 @@ void LLSimpleXUIParser::startElement(const char *name, const char **atts) } +void LLSimpleXUIParser::endElement(const char *name) +{ + bool has_text = processText(); + + // no text, attributes, or children + if (!has_text && mEmptyLeafNode.back()) + { + // submit this as a valueless name (even though there might be text contents we haven't seen yet) + mCurAttributeValueBegin = NO_VALUE_MARKER; + mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently); + } + + if (--mOutputStack.back().second == 0) + { + if (mOutputStack.empty()) + { + LL_ERRS("ReadXUI") << "Parameter block output stack popped while empty." << LL_ENDL; + } + mOutputStack.pop_back(); + } + + S32 num_tokens_to_pop = mTokenSizeStack.back(); + mTokenSizeStack.pop_back(); + while(num_tokens_to_pop-- > 0) + { + mNameStack.pop_back(); + } + mScope.pop_back(); + mEmptyLeafNode.pop_back(); +} + bool LLSimpleXUIParser::readAttributes(const char **atts) { typedef boost::tokenizer<boost::char_separator<char> > tokenizer; @@ -1268,7 +1426,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 +1448,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(); @@ -1301,43 +1459,6 @@ bool LLSimpleXUIParser::processText() return false; } -void LLSimpleXUIParser::endElement(const char *name) -{ - bool has_text = processText(); - - // no text, attributes, or children - if (!has_text && mEmptyLeafNode.back()) - { - // submit this as a valueless name (even though there might be text contents we haven't seen yet) - mCurAttributeValueBegin = NO_VALUE_MARKER; - mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently); - } - - if (--mOutputStack.back().second == 0) - { - if (mOutputStack.empty()) - { - LL_ERRS("ReadXUI") << "Parameter block output stack popped while empty." << LL_ENDL; - } - mOutputStack.pop_back(); - } - - S32 num_tokens_to_pop = mTokenSizeStack.back(); - mTokenSizeStack.pop_back(); - while(num_tokens_to_pop-- > 0) - { - mNameStack.pop_back(); - } - mScope.pop_back(); - mEmptyLeafNode.pop_back(); -} - -void LLSimpleXUIParser::characterData(const char *s, int len) -{ - mTextContents += std::string(s, len); -} - - /*virtual*/ std::string LLSimpleXUIParser::getCurrentElementName() { std::string full_name; @@ -1351,8 +1472,6 @@ void LLSimpleXUIParser::characterData(const char *s, int len) return full_name; } -const S32 LINE_NUMBER_HERE = 0; - void LLSimpleXUIParser::parserWarning(const std::string& message) { #ifdef LL_WINDOWS @@ -1376,7 +1495,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; |