From b2028085fdfddfd5a7ac0f52d9f34b84457b3b98 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Wed, 4 Aug 2010 19:02:30 -0700 Subject: first pass at faster XUI parsing (no recursion support yet) also made LLSD->param block parsing faster --- indra/llxuixml/llxuiparser.cpp | 511 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 455 insertions(+), 56 deletions(-) (limited to 'indra/llxuixml/llxuiparser.cpp') diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index dbc20a5a1e..00128c978a 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -35,11 +35,16 @@ #include "llxuiparser.h" #include "llxmlnode.h" +#include "expat/expat.h" #include #include +//#include +#include #include "lluicolor.h" +using namespace BOOST_SPIRIT_CLASSIC_NS; + const S32 MAX_STRING_ATTRIBUTE_SIZE = 40; // @@ -370,34 +375,20 @@ LLXUIParser::LLXUIParser() : mLastWriteGeneration(-1), mCurReadDepth(0) { - registerParserFuncs(boost::bind(&LLXUIParser::readBoolValue, this, _1), - boost::bind(&LLXUIParser::writeBoolValue, this, _1, _2)); - registerParserFuncs(boost::bind(&LLXUIParser::readStringValue, this, _1), - boost::bind(&LLXUIParser::writeStringValue, this, _1, _2)); - registerParserFuncs(boost::bind(&LLXUIParser::readU8Value, this, _1), - boost::bind(&LLXUIParser::writeU8Value, this, _1, _2)); - registerParserFuncs(boost::bind(&LLXUIParser::readS8Value, this, _1), - boost::bind(&LLXUIParser::writeS8Value, this, _1, _2)); - registerParserFuncs(boost::bind(&LLXUIParser::readU16Value, this, _1), - boost::bind(&LLXUIParser::writeU16Value, this, _1, _2)); - registerParserFuncs(boost::bind(&LLXUIParser::readS16Value, this, _1), - boost::bind(&LLXUIParser::writeS16Value, this, _1, _2)); - registerParserFuncs(boost::bind(&LLXUIParser::readU32Value, this, _1), - boost::bind(&LLXUIParser::writeU32Value, this, _1, _2)); - registerParserFuncs(boost::bind(&LLXUIParser::readS32Value, this, _1), - boost::bind(&LLXUIParser::writeS32Value, this, _1, _2)); - registerParserFuncs(boost::bind(&LLXUIParser::readF32Value, this, _1), - boost::bind(&LLXUIParser::writeF32Value, this, _1, _2)); - registerParserFuncs(boost::bind(&LLXUIParser::readF64Value, this, _1), - boost::bind(&LLXUIParser::writeF64Value, this, _1, _2)); - registerParserFuncs(boost::bind(&LLXUIParser::readColor4Value, this, _1), - boost::bind(&LLXUIParser::writeColor4Value, this, _1, _2)); - registerParserFuncs(boost::bind(&LLXUIParser::readUIColorValue, this, _1), - boost::bind(&LLXUIParser::writeUIColorValue, this, _1, _2)); - registerParserFuncs(boost::bind(&LLXUIParser::readUUIDValue, this, _1), - boost::bind(&LLXUIParser::writeUUIDValue, this, _1, _2)); - registerParserFuncs(boost::bind(&LLXUIParser::readSDValue, this, _1), - boost::bind(&LLXUIParser::writeSDValue, this, _1, _2)); + registerParserFuncs(readBoolValue, boost::bind(&LLXUIParser::writeBoolValue, this, _1, _2)); + registerParserFuncs(readStringValue, boost::bind(&LLXUIParser::writeStringValue, this, _1, _2)); + registerParserFuncs(readU8Value, boost::bind(&LLXUIParser::writeU8Value, this, _1, _2)); + registerParserFuncs(readS8Value, boost::bind(&LLXUIParser::writeS8Value, this, _1, _2)); + registerParserFuncs(readU16Value, boost::bind(&LLXUIParser::writeU16Value, this, _1, _2)); + registerParserFuncs(readS16Value, boost::bind(&LLXUIParser::writeS16Value, this, _1, _2)); + registerParserFuncs(readU32Value, boost::bind(&LLXUIParser::writeU32Value, this, _1, _2)); + registerParserFuncs(readS32Value, boost::bind(&LLXUIParser::writeS32Value, this, _1, _2)); + registerParserFuncs(readF32Value, boost::bind(&LLXUIParser::writeF32Value, this, _1, _2)); + registerParserFuncs(readF64Value, boost::bind(&LLXUIParser::writeF64Value, this, _1, _2)); + registerParserFuncs(readColor4Value, boost::bind(&LLXUIParser::writeColor4Value, this, _1, _2)); + registerParserFuncs(readUIColorValue, boost::bind(&LLXUIParser::writeUIColorValue, this, _1, _2)); + registerParserFuncs(readUUIDValue, boost::bind(&LLXUIParser::writeUUIDValue, this, _1, _2)); + registerParserFuncs(readSDValue, boost::bind(&LLXUIParser::writeSDValue, this, _1, _2)); } static LLFastTimer::DeclareTimer FTM_PARSE_XUI("XUI Parsing"); @@ -621,10 +612,11 @@ LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack) } -bool LLXUIParser::readBoolValue(void* val_ptr) +bool LLXUIParser::readBoolValue(Parser& parser, void* val_ptr) { S32 value; - bool success = mCurReadNode->getBoolValue(1, &value); + LLXUIParser& self = static_cast(parser); + bool success = self.mCurReadNode->getBoolValue(1, &value); *((bool*)val_ptr) = (value != FALSE); return success; } @@ -640,9 +632,10 @@ bool LLXUIParser::writeBoolValue(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readStringValue(void* val_ptr) +bool LLXUIParser::readStringValue(Parser& parser, void* val_ptr) { - *((std::string*)val_ptr) = mCurReadNode->getSanitizedValue(); + LLXUIParser& self = static_cast(parser); + *((std::string*)val_ptr) = self.mCurReadNode->getSanitizedValue(); return true; } @@ -677,9 +670,10 @@ bool LLXUIParser::writeStringValue(const void* val_ptr, const name_stack_t& stac return false; } -bool LLXUIParser::readU8Value(void* val_ptr) +bool LLXUIParser::readU8Value(Parser& parser, void* val_ptr) { - return mCurReadNode->getByteValue(1, (U8*)val_ptr); + LLXUIParser& self = static_cast(parser); + return self.mCurReadNode->getByteValue(1, (U8*)val_ptr); } bool LLXUIParser::writeU8Value(const void* val_ptr, const name_stack_t& stack) @@ -693,10 +687,11 @@ bool LLXUIParser::writeU8Value(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readS8Value(void* val_ptr) +bool LLXUIParser::readS8Value(Parser& parser, void* val_ptr) { + LLXUIParser& self = static_cast(parser); S32 value; - if(mCurReadNode->getIntValue(1, &value)) + if(self.mCurReadNode->getIntValue(1, &value)) { *((S8*)val_ptr) = value; return true; @@ -715,10 +710,11 @@ bool LLXUIParser::writeS8Value(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readU16Value(void* val_ptr) +bool LLXUIParser::readU16Value(Parser& parser, void* val_ptr) { + LLXUIParser& self = static_cast(parser); U32 value; - if(mCurReadNode->getUnsignedValue(1, &value)) + if(self.mCurReadNode->getUnsignedValue(1, &value)) { *((U16*)val_ptr) = value; return true; @@ -737,10 +733,11 @@ bool LLXUIParser::writeU16Value(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readS16Value(void* val_ptr) +bool LLXUIParser::readS16Value(Parser& parser, void* val_ptr) { + LLXUIParser& self = static_cast(parser); S32 value; - if(mCurReadNode->getIntValue(1, &value)) + if(self.mCurReadNode->getIntValue(1, &value)) { *((S16*)val_ptr) = value; return true; @@ -759,9 +756,10 @@ bool LLXUIParser::writeS16Value(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readU32Value(void* val_ptr) +bool LLXUIParser::readU32Value(Parser& parser, void* val_ptr) { - return mCurReadNode->getUnsignedValue(1, (U32*)val_ptr); + LLXUIParser& self = static_cast(parser); + return self.mCurReadNode->getUnsignedValue(1, (U32*)val_ptr); } bool LLXUIParser::writeU32Value(const void* val_ptr, const name_stack_t& stack) @@ -775,9 +773,10 @@ bool LLXUIParser::writeU32Value(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readS32Value(void* val_ptr) +bool LLXUIParser::readS32Value(Parser& parser, void* val_ptr) { - return mCurReadNode->getIntValue(1, (S32*)val_ptr); + LLXUIParser& self = static_cast(parser); + return self.mCurReadNode->getIntValue(1, (S32*)val_ptr); } bool LLXUIParser::writeS32Value(const void* val_ptr, const name_stack_t& stack) @@ -791,9 +790,10 @@ bool LLXUIParser::writeS32Value(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readF32Value(void* val_ptr) +bool LLXUIParser::readF32Value(Parser& parser, void* val_ptr) { - return mCurReadNode->getFloatValue(1, (F32*)val_ptr); + LLXUIParser& self = static_cast(parser); + return self.mCurReadNode->getFloatValue(1, (F32*)val_ptr); } bool LLXUIParser::writeF32Value(const void* val_ptr, const name_stack_t& stack) @@ -807,9 +807,10 @@ bool LLXUIParser::writeF32Value(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readF64Value(void* val_ptr) +bool LLXUIParser::readF64Value(Parser& parser, void* val_ptr) { - return mCurReadNode->getDoubleValue(1, (F64*)val_ptr); + LLXUIParser& self = static_cast(parser); + return self.mCurReadNode->getDoubleValue(1, (F64*)val_ptr); } bool LLXUIParser::writeF64Value(const void* val_ptr, const name_stack_t& stack) @@ -823,10 +824,11 @@ bool LLXUIParser::writeF64Value(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readColor4Value(void* val_ptr) +bool LLXUIParser::readColor4Value(Parser& parser, void* val_ptr) { + LLXUIParser& self = static_cast(parser); LLColor4* colorp = (LLColor4*)val_ptr; - if(mCurReadNode->getFloatValue(4, colorp->mV) >= 3) + if(self.mCurReadNode->getFloatValue(4, colorp->mV) >= 3) { return true; } @@ -846,11 +848,12 @@ bool LLXUIParser::writeColor4Value(const void* val_ptr, const name_stack_t& stac return false; } -bool LLXUIParser::readUIColorValue(void* val_ptr) +bool LLXUIParser::readUIColorValue(Parser& parser, void* val_ptr) { + LLXUIParser& self = static_cast(parser); LLUIColor* param = (LLUIColor*)val_ptr; LLColor4 color; - bool success = mCurReadNode->getFloatValue(4, color.mV) >= 3; + bool success = self.mCurReadNode->getFloatValue(4, color.mV) >= 3; if (success) { param->set(color); @@ -874,11 +877,12 @@ bool LLXUIParser::writeUIColorValue(const void* val_ptr, const name_stack_t& sta return false; } -bool LLXUIParser::readUUIDValue(void* val_ptr) +bool LLXUIParser::readUUIDValue(Parser& parser, void* val_ptr) { + LLXUIParser& self = static_cast(parser); LLUUID temp_id; // LLUUID::set is destructive, so use temporary value - if (temp_id.set(mCurReadNode->getSanitizedValue())) + if (temp_id.set(self.mCurReadNode->getSanitizedValue())) { *(LLUUID*)(val_ptr) = temp_id; return true; @@ -897,9 +901,10 @@ bool LLXUIParser::writeUUIDValue(const void* val_ptr, const name_stack_t& stack) return false; } -bool LLXUIParser::readSDValue(void* val_ptr) +bool LLXUIParser::readSDValue(Parser& parser, void* val_ptr) { - *((LLSD*)val_ptr) = LLSD(mCurReadNode->getSanitizedValue()); + LLXUIParser& self = static_cast(parser); + *((LLSD*)val_ptr) = LLSD(self.mCurReadNode->getSanitizedValue()); return true; } @@ -968,3 +973,397 @@ void LLXUIParser::parserError(const std::string& message) Parser::parserError(message); #endif } + + +// +// LLFastXUIParser +// + +struct ScopedFile +{ + ScopedFile( const std::string& filename, const char* accessmode ) + { + mFile = LLFile::fopen(filename, accessmode); + } + + ~ScopedFile() + { + fclose(mFile); + mFile = NULL; + } + + S32 getRemainingBytes() + { + if (!isOpen()) return 0; + + S32 cur_pos = ftell(mFile); + fseek(mFile, 0L, SEEK_END); + S32 file_size = ftell(mFile); + fseek(mFile, cur_pos, SEEK_SET); + return file_size - cur_pos; + } + + bool isOpen() { return mFile != NULL; } + + LLFILE* mFile; +}; + +LLFastXUIParser::LLFastXUIParser() +: mLastWriteGeneration(-1), + mCurReadDepth(0) +{ + registerParserFuncs(readBoolValue, NULL); + registerParserFuncs(readStringValue, NULL); + registerParserFuncs(readU8Value, NULL); + registerParserFuncs(readS8Value, NULL); + registerParserFuncs(readU16Value, NULL); + registerParserFuncs(readS16Value, NULL); + registerParserFuncs(readU32Value, NULL); + registerParserFuncs(readS32Value, NULL); + registerParserFuncs(readF32Value, NULL); + registerParserFuncs(readF64Value, NULL); + registerParserFuncs(readColor4Value, NULL); + registerParserFuncs(readUIColorValue, NULL); + registerParserFuncs(readUUIDValue, NULL); + registerParserFuncs(readSDValue, NULL); +} + +LLFastXUIParser::~LLFastXUIParser() +{ +} + + +bool LLFastXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent) +{ + LLFastTimer timer(FTM_PARSE_XUI); + + mParser = XML_ParserCreate(NULL); + XML_SetUserData(mParser, this); + XML_SetElementHandler( mParser, startElementHandler, endElementHandler); + XML_SetCharacterDataHandler( mParser, characterDataHandler); + + mBlock = █ + mNameStack.clear(); + mCurFileName = filename; + mCurReadDepth = 0; + setParseSilently(silent); + + ScopedFile file(filename, "rb"); + if( !file.isOpen() ) + { + LL_WARNS("ReadXUI") << "Unable to open file " << filename << LL_ENDL; + return false; + } + + S32 bytes_read = 0; + + S32 buffer_size = file.getRemainingBytes(); + void* buffer = XML_GetBuffer(mParser, buffer_size); + if( !buffer ) + { + LL_WARNS("ReadXUI") << "Unable to allocate XML buffer while reading file " << filename << LL_ENDL; + XML_ParserFree( mParser ); + return false; + } + + bytes_read = (S32)fread(buffer, 1, buffer_size, file.mFile); + if( bytes_read <= 0 ) + { + LL_WARNS("ReadXUI") << "Error while reading file " << filename << LL_ENDL; + XML_ParserFree( mParser ); + return false; + } + + if( !XML_ParseBuffer(mParser, bytes_read, TRUE ) ) + { + LL_WARNS("ReadXUI") << "Error while parsing file " << filename << LL_ENDL; + XML_ParserFree( mParser ); + return false; + } + + XML_ParserFree( mParser ); + return true; +} + +void LLFastXUIParser::startElementHandler(void *userData, const char *name, const char **atts) +{ + LLFastXUIParser* self = reinterpret_cast(userData); + self->startElement(name, atts); +} + +void LLFastXUIParser::endElementHandler(void *userData, const char *name) +{ + LLFastXUIParser* self = reinterpret_cast(userData); + self->endElement(name); +} + +void LLFastXUIParser::characterDataHandler(void *userData, const char *s, int len) +{ + LLFastXUIParser* self = reinterpret_cast(userData); + self->characterData(s, len); +} + +void LLFastXUIParser::startElement(const char *name, const char **atts) +{ + typedef boost::tokenizer > tokenizer; + boost::char_separator sep("."); + + mCurReadDepth++; + S32 num_tokens_pushed = 0; + std::string child_name(name); + + if (mCurReadDepth > 1) + { + // 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. will interpret 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()) + { + return; + } + + // check for proper nesting + if(!mScope.empty() && *name_token_it != mScope.back()) + { + return; + } + + // 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++; + } + mScope.push_back(mNameStack.back().first); + } + } + else + { + mScope.push_back(name); + } + + mTokenSizeStack.push_back(num_tokens_pushed); + readAttributes(atts); +} + +bool LLFastXUIParser::readAttributes(const char **atts) +{ + typedef boost::tokenizer > tokenizer; + boost::char_separator sep("."); + + bool any_parsed = false; + for(S32 i = 0; atts[i] && atts[i+1]; i += 2 ) + { + std::string attribute_name(atts[i]); + mCurAttributeValueBegin = atts[i+1]; + + S32 num_tokens_pushed = 0; + 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 > 1; + any_parsed |= mBlock->submitValue(mNameStack, *this, silent); + + while(num_tokens_pushed-- > 0) + { + mNameStack.pop_back(); + } + } + return any_parsed; +} + + +void LLFastXUIParser::endElement(const char *name) +{ + mCurReadDepth--; + S32 num_tokens_to_pop = mTokenSizeStack.back(); + mTokenSizeStack.pop_back(); + while(num_tokens_to_pop-- > 0) + { + mNameStack.pop_back(); + } + mScope.pop_back(); +} + +void LLFastXUIParser::characterData(const char *s, int len) +{ +} + + +/*virtual*/ std::string LLFastXUIParser::getCurrentElementName() +{ + std::string full_name; + for (name_stack_t::iterator it = mNameStack.begin(); + it != mNameStack.end(); + ++it) + { + full_name += it->first + "."; // build up dotted names: "button.param.nestedparam." + } + + return full_name; +} + +const S32 LINE_NUMBER_HERE = 0; + +void LLFastXUIParser::parserWarning(const std::string& message) +{ +#ifdef LL_WINDOWS + // use Visual Studo friendly formatting of output message for easy access to originating xml + llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str()); + utf16str += '\n'; + OutputDebugString(utf16str.c_str()); +#else + Parser::parserWarning(message); +#endif +} + +void LLFastXUIParser::parserError(const std::string& message) +{ +#ifdef LL_WINDOWS + llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str()); + utf16str += '\n'; + OutputDebugString(utf16str.c_str()); +#else + Parser::parserError(message); +#endif +} + +bool LLFastXUIParser::readBoolValue(Parser& parser, void* val_ptr) +{ + LLFastXUIParser& self = static_cast(parser); + if (!strcmp(self.mCurAttributeValueBegin, "true")) + { + *((bool*)val_ptr) = true; + return true; + } + else if (!strcmp(self.mCurAttributeValueBegin, "false")) + { + *((bool*)val_ptr) = false; + return true; + } + + return false; +} + +bool LLFastXUIParser::readStringValue(Parser& parser, void* val_ptr) +{ + LLFastXUIParser& self = static_cast(parser); + *((std::string*)val_ptr) = self.mCurAttributeValueBegin; + return true; +} + +bool LLFastXUIParser::readU8Value(Parser& parser, void* val_ptr) +{ + LLFastXUIParser& self = static_cast(parser); + return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U8*)val_ptr)]).full; +} + +bool LLFastXUIParser::readS8Value(Parser& parser, void* val_ptr) +{ + LLFastXUIParser& self = static_cast(parser); + return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S8*)val_ptr)]).full; +} + +bool LLFastXUIParser::readU16Value(Parser& parser, void* val_ptr) +{ + LLFastXUIParser& self = static_cast(parser); + return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U16*)val_ptr)]).full; +} + +bool LLFastXUIParser::readS16Value(Parser& parser, void* val_ptr) +{ + LLFastXUIParser& self = static_cast(parser); + return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S16*)val_ptr)]).full; +} + +bool LLFastXUIParser::readU32Value(Parser& parser, void* val_ptr) +{ + LLFastXUIParser& self = static_cast(parser); + return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U32*)val_ptr)]).full; +} + +bool LLFastXUIParser::readS32Value(Parser& parser, void* val_ptr) +{ + LLFastXUIParser& self = static_cast(parser); + return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S32*)val_ptr)]).full; +} + +bool LLFastXUIParser::readF32Value(Parser& parser, void* val_ptr) +{ + LLFastXUIParser& self = static_cast(parser); + return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F32*)val_ptr)]).full; +} + +bool LLFastXUIParser::readF64Value(Parser& parser, void* val_ptr) +{ + LLFastXUIParser& self = static_cast(parser); + return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F64*)val_ptr)]).full; +} + +bool LLFastXUIParser::readColor4Value(Parser& parser, void* val_ptr) +{ + LLFastXUIParser& self = static_cast(parser); + LLColor4 value; + + if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full) + { + *(LLColor4*)(val_ptr) = value; + return true; + } + return false; +} + +bool LLFastXUIParser::readUIColorValue(Parser& parser, void* val_ptr) +{ + LLFastXUIParser& self = static_cast(parser); + LLColor4 value; + LLUIColor* colorp = (LLUIColor*)val_ptr; + + if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full) + { + colorp->set(value); + return true; + } + return false; +} + +bool LLFastXUIParser::readUUIDValue(Parser& parser, void* val_ptr) +{ + LLFastXUIParser& self = static_cast(parser); + LLUUID temp_id; + // LLUUID::set is destructive, so use temporary value + if (temp_id.set(self.mCurAttributeValueBegin)) + { + *(LLUUID*)(val_ptr) = temp_id; + return true; + } + return false; +} + +bool LLFastXUIParser::readSDValue(Parser& parser, void* val_ptr) +{ + LLFastXUIParser& self = static_cast(parser); + *((LLSD*)val_ptr) = LLSD(self.mCurAttributeValueBegin); + return true; +} \ No newline at end of file -- cgit v1.2.3 From d26e380a06b343bc46010922de46e9664831e3b4 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 5 Aug 2010 13:19:19 -0700 Subject: added newlines at end to make Linux builds happy --- indra/llxuixml/llxuiparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llxuixml/llxuiparser.cpp') diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index 00128c978a..16571a9969 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -1366,4 +1366,4 @@ bool LLFastXUIParser::readSDValue(Parser& parser, void* val_ptr) LLFastXUIParser& self = static_cast(parser); *((LLSD*)val_ptr) = LLSD(self.mCurAttributeValueBegin); return true; -} \ No newline at end of file +} -- cgit v1.2.3 From a974ed98d04d05d9c682e85d3b25cf591d2b58c0 Mon Sep 17 00:00:00 2001 From: Monroe Linden Date: Thu, 5 Aug 2010 14:18:55 -0700 Subject: Fix for a crash on startup. Richard sent me the diff for this one, just pushing it on his behalf. --- indra/llxuixml/llxuiparser.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/llxuixml/llxuiparser.cpp') diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index 16571a9969..fe85ac41cc 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -1122,6 +1122,7 @@ void LLFastXUIParser::startElement(const char *name, const char **atts) { mNameStack.push_back(std::make_pair(child_name, newParseGeneration())); num_tokens_pushed++; + mScope.push_back(child_name); } else { @@ -1154,7 +1155,7 @@ void LLFastXUIParser::startElement(const char *name, const char **atts) } else { - mScope.push_back(name); + mScope.push_back(child_name); } mTokenSizeStack.push_back(num_tokens_pushed); -- cgit v1.2.3 From 9609b2c81c1efc43c152e379ca56191c7295973a Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Fri, 6 Aug 2010 11:03:15 -0700 Subject: renamed LLFastXUIParser to LLSimpleXUIParser and added support for parsing xml node text contents --- indra/llxuixml/llxuiparser.cpp | 108 ++++++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 49 deletions(-) (limited to 'indra/llxuixml/llxuiparser.cpp') diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index 00128c978a..e010b4c125 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -976,7 +976,7 @@ void LLXUIParser::parserError(const std::string& message) // -// LLFastXUIParser +// LLSimpleXUIParser // struct ScopedFile @@ -1008,7 +1008,7 @@ struct ScopedFile LLFILE* mFile; }; -LLFastXUIParser::LLFastXUIParser() +LLSimpleXUIParser::LLSimpleXUIParser() : mLastWriteGeneration(-1), mCurReadDepth(0) { @@ -1028,19 +1028,19 @@ LLFastXUIParser::LLFastXUIParser() registerParserFuncs(readSDValue, NULL); } -LLFastXUIParser::~LLFastXUIParser() +LLSimpleXUIParser::~LLSimpleXUIParser() { } -bool LLFastXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent) +bool LLSimpleXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent) { LLFastTimer timer(FTM_PARSE_XUI); mParser = XML_ParserCreate(NULL); XML_SetUserData(mParser, this); - XML_SetElementHandler( mParser, startElementHandler, endElementHandler); - XML_SetCharacterDataHandler( mParser, characterDataHandler); + XML_SetElementHandler( mParser, startElementHandler, endElementHandler); + XML_SetCharacterDataHandler( mParser, characterDataHandler); mBlock = █ mNameStack.clear(); @@ -1085,25 +1085,25 @@ bool LLFastXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBloc return true; } -void LLFastXUIParser::startElementHandler(void *userData, const char *name, const char **atts) +void LLSimpleXUIParser::startElementHandler(void *userData, const char *name, const char **atts) { - LLFastXUIParser* self = reinterpret_cast(userData); + LLSimpleXUIParser* self = reinterpret_cast(userData); self->startElement(name, atts); } -void LLFastXUIParser::endElementHandler(void *userData, const char *name) +void LLSimpleXUIParser::endElementHandler(void *userData, const char *name) { - LLFastXUIParser* self = reinterpret_cast(userData); + LLSimpleXUIParser* self = reinterpret_cast(userData); self->endElement(name); } -void LLFastXUIParser::characterDataHandler(void *userData, const char *s, int len) +void LLSimpleXUIParser::characterDataHandler(void *userData, const char *s, int len) { - LLFastXUIParser* self = reinterpret_cast(userData); + LLSimpleXUIParser* self = reinterpret_cast(userData); self->characterData(s, len); } -void LLFastXUIParser::startElement(const char *name, const char **atts) +void LLSimpleXUIParser::startElement(const char *name, const char **atts) { typedef boost::tokenizer > tokenizer; boost::char_separator sep("."); @@ -1122,6 +1122,7 @@ void LLFastXUIParser::startElement(const char *name, const char **atts) { mNameStack.push_back(std::make_pair(child_name, newParseGeneration())); num_tokens_pushed++; + mScope.push_back(child_name); } else { @@ -1154,14 +1155,14 @@ void LLFastXUIParser::startElement(const char *name, const char **atts) } else { - mScope.push_back(name); + mScope.push_back(child_name); } mTokenSizeStack.push_back(num_tokens_pushed); readAttributes(atts); } -bool LLFastXUIParser::readAttributes(const char **atts) +bool LLSimpleXUIParser::readAttributes(const char **atts) { typedef boost::tokenizer > tokenizer; boost::char_separator sep("."); @@ -1194,8 +1195,16 @@ bool LLFastXUIParser::readAttributes(const char **atts) } -void LLFastXUIParser::endElement(const char *name) +void LLSimpleXUIParser::endElement(const char *name) { + if (!mTextContents.empty()) + { + mNameStack.push_back(std::make_pair(std::string("value"), newParseGeneration())); + mCurAttributeValueBegin = mTextContents.c_str(); + mBlock->submitValue(mNameStack, *this); + mNameStack.pop_back(); + mTextContents.clear(); + } mCurReadDepth--; S32 num_tokens_to_pop = mTokenSizeStack.back(); mTokenSizeStack.pop_back(); @@ -1206,12 +1215,13 @@ void LLFastXUIParser::endElement(const char *name) mScope.pop_back(); } -void LLFastXUIParser::characterData(const char *s, int len) +void LLSimpleXUIParser::characterData(const char *s, int len) { + mTextContents += std::string(s, len); } -/*virtual*/ std::string LLFastXUIParser::getCurrentElementName() +/*virtual*/ std::string LLSimpleXUIParser::getCurrentElementName() { std::string full_name; for (name_stack_t::iterator it = mNameStack.begin(); @@ -1226,7 +1236,7 @@ void LLFastXUIParser::characterData(const char *s, int len) const S32 LINE_NUMBER_HERE = 0; -void LLFastXUIParser::parserWarning(const std::string& message) +void LLSimpleXUIParser::parserWarning(const std::string& message) { #ifdef LL_WINDOWS // use Visual Studo friendly formatting of output message for easy access to originating xml @@ -1238,7 +1248,7 @@ void LLFastXUIParser::parserWarning(const std::string& message) #endif } -void LLFastXUIParser::parserError(const std::string& message) +void LLSimpleXUIParser::parserError(const std::string& message) { #ifdef LL_WINDOWS llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str()); @@ -1249,9 +1259,9 @@ void LLFastXUIParser::parserError(const std::string& message) #endif } -bool LLFastXUIParser::readBoolValue(Parser& parser, void* val_ptr) +bool LLSimpleXUIParser::readBoolValue(Parser& parser, void* val_ptr) { - LLFastXUIParser& self = static_cast(parser); + LLSimpleXUIParser& self = static_cast(parser); if (!strcmp(self.mCurAttributeValueBegin, "true")) { *((bool*)val_ptr) = true; @@ -1266,64 +1276,64 @@ bool LLFastXUIParser::readBoolValue(Parser& parser, void* val_ptr) return false; } -bool LLFastXUIParser::readStringValue(Parser& parser, void* val_ptr) +bool LLSimpleXUIParser::readStringValue(Parser& parser, void* val_ptr) { - LLFastXUIParser& self = static_cast(parser); + LLSimpleXUIParser& self = static_cast(parser); *((std::string*)val_ptr) = self.mCurAttributeValueBegin; return true; } -bool LLFastXUIParser::readU8Value(Parser& parser, void* val_ptr) +bool LLSimpleXUIParser::readU8Value(Parser& parser, void* val_ptr) { - LLFastXUIParser& self = static_cast(parser); + LLSimpleXUIParser& self = static_cast(parser); return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U8*)val_ptr)]).full; } -bool LLFastXUIParser::readS8Value(Parser& parser, void* val_ptr) +bool LLSimpleXUIParser::readS8Value(Parser& parser, void* val_ptr) { - LLFastXUIParser& self = static_cast(parser); + LLSimpleXUIParser& self = static_cast(parser); return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S8*)val_ptr)]).full; } -bool LLFastXUIParser::readU16Value(Parser& parser, void* val_ptr) +bool LLSimpleXUIParser::readU16Value(Parser& parser, void* val_ptr) { - LLFastXUIParser& self = static_cast(parser); + LLSimpleXUIParser& self = static_cast(parser); return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U16*)val_ptr)]).full; } -bool LLFastXUIParser::readS16Value(Parser& parser, void* val_ptr) +bool LLSimpleXUIParser::readS16Value(Parser& parser, void* val_ptr) { - LLFastXUIParser& self = static_cast(parser); + LLSimpleXUIParser& self = static_cast(parser); return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S16*)val_ptr)]).full; } -bool LLFastXUIParser::readU32Value(Parser& parser, void* val_ptr) +bool LLSimpleXUIParser::readU32Value(Parser& parser, void* val_ptr) { - LLFastXUIParser& self = static_cast(parser); + LLSimpleXUIParser& self = static_cast(parser); return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U32*)val_ptr)]).full; } -bool LLFastXUIParser::readS32Value(Parser& parser, void* val_ptr) +bool LLSimpleXUIParser::readS32Value(Parser& parser, void* val_ptr) { - LLFastXUIParser& self = static_cast(parser); + LLSimpleXUIParser& self = static_cast(parser); return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S32*)val_ptr)]).full; } -bool LLFastXUIParser::readF32Value(Parser& parser, void* val_ptr) +bool LLSimpleXUIParser::readF32Value(Parser& parser, void* val_ptr) { - LLFastXUIParser& self = static_cast(parser); + LLSimpleXUIParser& self = static_cast(parser); return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F32*)val_ptr)]).full; } -bool LLFastXUIParser::readF64Value(Parser& parser, void* val_ptr) +bool LLSimpleXUIParser::readF64Value(Parser& parser, void* val_ptr) { - LLFastXUIParser& self = static_cast(parser); + LLSimpleXUIParser& self = static_cast(parser); return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F64*)val_ptr)]).full; } -bool LLFastXUIParser::readColor4Value(Parser& parser, void* val_ptr) +bool LLSimpleXUIParser::readColor4Value(Parser& parser, void* val_ptr) { - LLFastXUIParser& self = static_cast(parser); + LLSimpleXUIParser& self = static_cast(parser); LLColor4 value; if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full) @@ -1334,9 +1344,9 @@ bool LLFastXUIParser::readColor4Value(Parser& parser, void* val_ptr) return false; } -bool LLFastXUIParser::readUIColorValue(Parser& parser, void* val_ptr) +bool LLSimpleXUIParser::readUIColorValue(Parser& parser, void* val_ptr) { - LLFastXUIParser& self = static_cast(parser); + LLSimpleXUIParser& self = static_cast(parser); LLColor4 value; LLUIColor* colorp = (LLUIColor*)val_ptr; @@ -1348,12 +1358,12 @@ bool LLFastXUIParser::readUIColorValue(Parser& parser, void* val_ptr) return false; } -bool LLFastXUIParser::readUUIDValue(Parser& parser, void* val_ptr) +bool LLSimpleXUIParser::readUUIDValue(Parser& parser, void* val_ptr) { - LLFastXUIParser& self = static_cast(parser); + LLSimpleXUIParser& self = static_cast(parser); LLUUID temp_id; // LLUUID::set is destructive, so use temporary value - if (temp_id.set(self.mCurAttributeValueBegin)) + if (temp_id.set(std::string(self.mCurAttributeValueBegin))) { *(LLUUID*)(val_ptr) = temp_id; return true; @@ -1361,9 +1371,9 @@ bool LLFastXUIParser::readUUIDValue(Parser& parser, void* val_ptr) return false; } -bool LLFastXUIParser::readSDValue(Parser& parser, void* val_ptr) +bool LLSimpleXUIParser::readSDValue(Parser& parser, void* val_ptr) { - LLFastXUIParser& self = static_cast(parser); + LLSimpleXUIParser& self = static_cast(parser); *((LLSD*)val_ptr) = LLSD(self.mCurAttributeValueBegin); return true; } \ No newline at end of file -- cgit v1.2.3 From 7b41819377ec1c6ffc835a0a05a1acf571f46aad Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Fri, 6 Aug 2010 11:49:43 -0700 Subject: removed spurious parsing of empty text contents --- indra/llxuixml/llxuiparser.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'indra/llxuixml/llxuiparser.cpp') diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index e010b4c125..b3cb71cd61 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -1199,11 +1199,15 @@ void LLSimpleXUIParser::endElement(const char *name) { if (!mTextContents.empty()) { - mNameStack.push_back(std::make_pair(std::string("value"), newParseGeneration())); - mCurAttributeValueBegin = mTextContents.c_str(); - mBlock->submitValue(mNameStack, *this); - mNameStack.pop_back(); - mTextContents.clear(); + LLStringUtil::trim(mTextContents); + if (!mTextContents.empty()) + { + mNameStack.push_back(std::make_pair(std::string("value"), newParseGeneration())); + mCurAttributeValueBegin = mTextContents.c_str(); + mBlock->submitValue(mNameStack, *this, false); + mNameStack.pop_back(); + mTextContents.clear(); + } } mCurReadDepth--; S32 num_tokens_to_pop = mTokenSizeStack.back(); -- cgit v1.2.3 From 65c9914d23022df6a39db50ce295750f08695893 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Mon, 23 Aug 2010 11:03:19 -0700 Subject: made Params parsers not act as singletons --- indra/llxuixml/llxuiparser.cpp | 202 +++++++++++++++++++++++++---------------- 1 file changed, 126 insertions(+), 76 deletions(-) (limited to 'indra/llxuixml/llxuiparser.cpp') diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index d856efb008..220171fb79 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -47,10 +47,16 @@ using namespace BOOST_SPIRIT_CLASSIC_NS; const S32 MAX_STRING_ATTRIBUTE_SIZE = 40; +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; + + // // LLXSDWriter // LLXSDWriter::LLXSDWriter() +: Parser(sXSDReadFuncs, sXSDWriteFuncs, sXSDInspectFuncs) { registerInspectFunc(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:boolean", _1, _2, _3, _4)); registerInspectFunc(boost::bind(&LLXSDWriter::writeAttribute, this, "xs:string", _1, _2, _3, _4)); @@ -368,27 +374,35 @@ void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& p fclose(xsd_file); } +static LLInitParam::Parser::parser_read_func_map_t sXUIReadFuncs; +static LLInitParam::Parser::parser_write_func_map_t sXUIWriteFuncs; +static LLInitParam::Parser::parser_inspect_func_map_t sXUIInspectFuncs; + // // LLXUIParser // LLXUIParser::LLXUIParser() -: mLastWriteGeneration(-1), +: Parser(sXUIReadFuncs, sXUIWriteFuncs, sXUIInspectFuncs), + mLastWriteGeneration(-1), mCurReadDepth(0) { - registerParserFuncs(readBoolValue, boost::bind(&LLXUIParser::writeBoolValue, this, _1, _2)); - registerParserFuncs(readStringValue, boost::bind(&LLXUIParser::writeStringValue, this, _1, _2)); - registerParserFuncs(readU8Value, boost::bind(&LLXUIParser::writeU8Value, this, _1, _2)); - registerParserFuncs(readS8Value, boost::bind(&LLXUIParser::writeS8Value, this, _1, _2)); - registerParserFuncs(readU16Value, boost::bind(&LLXUIParser::writeU16Value, this, _1, _2)); - registerParserFuncs(readS16Value, boost::bind(&LLXUIParser::writeS16Value, this, _1, _2)); - registerParserFuncs(readU32Value, boost::bind(&LLXUIParser::writeU32Value, this, _1, _2)); - registerParserFuncs(readS32Value, boost::bind(&LLXUIParser::writeS32Value, this, _1, _2)); - registerParserFuncs(readF32Value, boost::bind(&LLXUIParser::writeF32Value, this, _1, _2)); - registerParserFuncs(readF64Value, boost::bind(&LLXUIParser::writeF64Value, this, _1, _2)); - registerParserFuncs(readColor4Value, boost::bind(&LLXUIParser::writeColor4Value, this, _1, _2)); - registerParserFuncs(readUIColorValue, boost::bind(&LLXUIParser::writeUIColorValue, this, _1, _2)); - registerParserFuncs(readUUIDValue, boost::bind(&LLXUIParser::writeUUIDValue, this, _1, _2)); - registerParserFuncs(readSDValue, boost::bind(&LLXUIParser::writeSDValue, this, _1, _2)); + if (sXUIReadFuncs.empty()) + { + registerParserFuncs(readBoolValue, writeBoolValue); + registerParserFuncs(readStringValue, writeStringValue); + registerParserFuncs(readU8Value, writeU8Value); + registerParserFuncs(readS8Value, writeS8Value); + registerParserFuncs(readU16Value, writeU16Value); + registerParserFuncs(readS16Value, writeS16Value); + registerParserFuncs(readU32Value, writeU32Value); + registerParserFuncs(readS32Value, writeS32Value); + registerParserFuncs(readF32Value, writeF32Value); + registerParserFuncs(readF64Value, writeF64Value); + registerParserFuncs(readColor4Value, writeColor4Value); + registerParserFuncs(readUIColorValue, writeUIColorValue); + registerParserFuncs(readUUIDValue, writeUUIDValue); + registerParserFuncs(readSDValue, writeSDValue); + } } static LLFastTimer::DeclareTimer FTM_PARSE_XUI("XUI Parsing"); @@ -621,9 +635,10 @@ bool LLXUIParser::readBoolValue(Parser& parser, void* val_ptr) return success; } -bool LLXUIParser::writeBoolValue(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeBoolValue(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setBoolValue(*((bool*)val_ptr)); @@ -639,9 +654,10 @@ bool LLXUIParser::readStringValue(Parser& parser, void* val_ptr) return true; } -bool LLXUIParser::writeStringValue(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeStringValue(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { const std::string* string_val = reinterpret_cast(val_ptr); @@ -676,9 +692,10 @@ bool LLXUIParser::readU8Value(Parser& parser, void* val_ptr) return self.mCurReadNode->getByteValue(1, (U8*)val_ptr); } -bool LLXUIParser::writeU8Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeU8Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setUnsignedValue(*((U8*)val_ptr)); @@ -699,9 +716,10 @@ bool LLXUIParser::readS8Value(Parser& parser, void* val_ptr) return false; } -bool LLXUIParser::writeS8Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeS8Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setIntValue(*((S8*)val_ptr)); @@ -722,9 +740,10 @@ bool LLXUIParser::readU16Value(Parser& parser, void* val_ptr) return false; } -bool LLXUIParser::writeU16Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeU16Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setUnsignedValue(*((U16*)val_ptr)); @@ -745,9 +764,10 @@ bool LLXUIParser::readS16Value(Parser& parser, void* val_ptr) return false; } -bool LLXUIParser::writeS16Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeS16Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setIntValue(*((S16*)val_ptr)); @@ -762,9 +782,10 @@ bool LLXUIParser::readU32Value(Parser& parser, void* val_ptr) return self.mCurReadNode->getUnsignedValue(1, (U32*)val_ptr); } -bool LLXUIParser::writeU32Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeU32Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setUnsignedValue(*((U32*)val_ptr)); @@ -779,9 +800,10 @@ bool LLXUIParser::readS32Value(Parser& parser, void* val_ptr) return self.mCurReadNode->getIntValue(1, (S32*)val_ptr); } -bool LLXUIParser::writeS32Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeS32Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setIntValue(*((S32*)val_ptr)); @@ -796,9 +818,10 @@ bool LLXUIParser::readF32Value(Parser& parser, void* val_ptr) return self.mCurReadNode->getFloatValue(1, (F32*)val_ptr); } -bool LLXUIParser::writeF32Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeF32Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setFloatValue(*((F32*)val_ptr)); @@ -813,9 +836,10 @@ bool LLXUIParser::readF64Value(Parser& parser, void* val_ptr) return self.mCurReadNode->getDoubleValue(1, (F64*)val_ptr); } -bool LLXUIParser::writeF64Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeF64Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setDoubleValue(*((F64*)val_ptr)); @@ -836,9 +860,10 @@ bool LLXUIParser::readColor4Value(Parser& parser, void* val_ptr) return false; } -bool LLXUIParser::writeColor4Value(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeColor4Value(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { LLColor4 color = *((LLColor4*)val_ptr); @@ -862,9 +887,10 @@ bool LLXUIParser::readUIColorValue(Parser& parser, void* val_ptr) return false; } -bool LLXUIParser::writeUIColorValue(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeUIColorValue(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { LLUIColor color = *((LLUIColor*)val_ptr); @@ -890,9 +916,10 @@ bool LLXUIParser::readUUIDValue(Parser& parser, void* val_ptr) return false; } -bool LLXUIParser::writeUUIDValue(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeUUIDValue(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast(parser); + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { node->setStringValue(((LLUUID*)val_ptr)->asString()); @@ -908,9 +935,11 @@ bool LLXUIParser::readSDValue(Parser& parser, void* val_ptr) return true; } -bool LLXUIParser::writeSDValue(const void* val_ptr, const name_stack_t& stack) +bool LLXUIParser::writeSDValue(Parser& parser, const void* val_ptr, const name_stack_t& stack) { - LLXMLNodePtr node = getNode(stack); + LLXUIParser& self = static_cast(parser); + + LLXMLNodePtr node = self.getNode(stack); if (node.notNull()) { std::string string_val = ((LLSD*)val_ptr)->asString(); @@ -1007,25 +1036,33 @@ 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; -LLSimpleXUIParser::LLSimpleXUIParser() -: mLastWriteGeneration(-1), - mCurReadDepth(0) +LLSimpleXUIParser::LLSimpleXUIParser(LLSimpleXUIParser::element_start_callback_t element_cb) +: Parser(sSimpleXUIReadFuncs, sSimpleXUIWriteFuncs, sSimpleXUIInspectFuncs), + mLastWriteGeneration(-1), + mCurReadDepth(0), + mElementCB(element_cb) { - registerParserFuncs(readBoolValue, NULL); - registerParserFuncs(readStringValue, NULL); - registerParserFuncs(readU8Value, NULL); - registerParserFuncs(readS8Value, NULL); - registerParserFuncs(readU16Value, NULL); - registerParserFuncs(readS16Value, NULL); - registerParserFuncs(readU32Value, NULL); - registerParserFuncs(readS32Value, NULL); - registerParserFuncs(readF32Value, NULL); - registerParserFuncs(readF64Value, NULL); - registerParserFuncs(readColor4Value, NULL); - registerParserFuncs(readUIColorValue, NULL); - registerParserFuncs(readUUIDValue, NULL); - registerParserFuncs(readSDValue, NULL); + if (sSimpleXUIReadFuncs.empty()) + { + registerParserFuncs(readBoolValue); + registerParserFuncs(readStringValue); + registerParserFuncs(readU8Value); + registerParserFuncs(readS8Value); + registerParserFuncs(readU16Value); + registerParserFuncs(readS16Value); + registerParserFuncs(readU32Value); + registerParserFuncs(readS32Value); + registerParserFuncs(readF32Value); + registerParserFuncs(readF64Value); + registerParserFuncs(readColor4Value); + registerParserFuncs(readUIColorValue); + registerParserFuncs(readUUIDValue); + registerParserFuncs(readSDValue); + } } LLSimpleXUIParser::~LLSimpleXUIParser() @@ -1042,7 +1079,7 @@ bool LLSimpleXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBl XML_SetElementHandler( mParser, startElementHandler, endElementHandler); XML_SetCharacterDataHandler( mParser, characterDataHandler); - mBlock = █ + mOutputStack.push_back(std::make_pair(&block, 0)); mNameStack.clear(); mCurFileName = filename; mCurReadDepth = 0; @@ -1108,16 +1145,25 @@ void LLSimpleXUIParser::startElement(const char *name, const char **atts) typedef boost::tokenizer > tokenizer; boost::char_separator sep("."); - mCurReadDepth++; + if (mElementCB) + { + LLInitParam::BaseBlock* blockp = mElementCB(*this, name); + if (blockp) + { + mOutputStack.push_back(std::make_pair(blockp, 0)); + } + } + + mOutputStack.back().second++; S32 num_tokens_pushed = 0; std::string child_name(name); - if (mCurReadDepth > 1) - { - // 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. will interpret as "button.rect" - // since there is no widget named "rect" + if (mOutputStack.back().second == 1) + { // root node for this block + mScope.push_back(child_name); + } + else + { // compound attribute if (child_name.find(".") == std::string::npos) { mNameStack.push_back(std::make_pair(child_name, newParseGeneration())); @@ -1153,10 +1199,6 @@ void LLSimpleXUIParser::startElement(const char *name, const char **atts) mScope.push_back(mNameStack.back().first); } } - else - { - mScope.push_back(child_name); - } mTokenSizeStack.push_back(num_tokens_pushed); readAttributes(atts); @@ -1183,8 +1225,7 @@ bool LLSimpleXUIParser::readAttributes(const char **atts) } // child nodes are not necessarily valid attributes, so don't complain once we've recursed - bool silent = mCurReadDepth > 1; - any_parsed |= mBlock->submitValue(mNameStack, *this, silent); + any_parsed |= mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently); while(num_tokens_pushed-- > 0) { @@ -1204,12 +1245,21 @@ void LLSimpleXUIParser::endElement(const char *name) { mNameStack.push_back(std::make_pair(std::string("value"), newParseGeneration())); mCurAttributeValueBegin = mTextContents.c_str(); - mBlock->submitValue(mNameStack, *this, false); + mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently); mNameStack.pop_back(); mTextContents.clear(); } } - mCurReadDepth--; + + 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) -- cgit v1.2.3 From 0daa627db4f1bba2f69ec717426b26593674d14c Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Tue, 24 Aug 2010 11:44:28 -0700 Subject: removed LLLayoutStack::fromXML custom xml parsing --- indra/llxuixml/llxuiparser.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'indra/llxuixml/llxuiparser.cpp') diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index 220171fb79..9bda96713e 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -411,6 +411,7 @@ void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, cons { LLFastTimer timer(FTM_PARSE_XUI); mNameStack.clear(); + mRootNodeName = node->getName()->mString; mCurFileName = filename; mCurReadDepth = 0; setParseSilently(silent); @@ -421,11 +422,11 @@ void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, cons } else { - readXUIImpl(node, std::string(node->getName()->mString), block); + readXUIImpl(node, block); } } -bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLInitParam::BaseBlock& block) +bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block) { typedef boost::tokenizer > tokenizer; boost::char_separator sep("."); @@ -492,7 +493,15 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLIn } // check for proper nesting - if(!scope.empty() && *name_token_it != scope) + if (mNameStack.empty()) + { + if (*name_token_it != mRootNodeName) + { + childp = childp->getNextSibling(); + continue; + } + } + else if(mNameStack.back().first != *name_token_it) { childp = childp->getNextSibling(); continue; @@ -510,7 +519,7 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, const std::string& scope, LLIn } // recurse and visit children XML nodes - if(readXUIImpl(childp, mNameStack.empty() ? scope : mNameStack.back().first, block)) + if(readXUIImpl(childp, block)) { // child node successfully parsed, remove from DOM -- cgit v1.2.3 From 369d12bcfb9e12799509a70566e1220d04d0e189 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Tue, 14 Sep 2010 10:47:43 -0700 Subject: fixed text contents parsing for LLSimpleXUIParser...each contiguous range of text is submitted as a new "value" element whenever an open/close tag is encountered --- indra/llxuixml/llxuiparser.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'indra/llxuixml/llxuiparser.cpp') diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index afc9b38246..e1ad9a5c71 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -1145,6 +1145,8 @@ void LLSimpleXUIParser::characterDataHandler(void *userData, const char *s, int void LLSimpleXUIParser::startElement(const char *name, const char **atts) { + processText(); + typedef boost::tokenizer > tokenizer; boost::char_separator sep("."); @@ -1238,8 +1240,7 @@ bool LLSimpleXUIParser::readAttributes(const char **atts) return any_parsed; } - -void LLSimpleXUIParser::endElement(const char *name) +void LLSimpleXUIParser::processText() { if (!mTextContents.empty()) { @@ -1250,9 +1251,14 @@ void LLSimpleXUIParser::endElement(const char *name) mCurAttributeValueBegin = mTextContents.c_str(); mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently); mNameStack.pop_back(); - mTextContents.clear(); } + mTextContents.clear(); } +} + +void LLSimpleXUIParser::endElement(const char *name) +{ + processText(); if (--mOutputStack.back().second == 0) { -- cgit v1.2.3