summaryrefslogtreecommitdiff
path: root/indra/llxuixml/llxuiparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llxuixml/llxuiparser.cpp')
-rw-r--r--indra/llxuixml/llxuiparser.cpp307
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;