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/llinitparam.h | 13 +- indra/llxuixml/llxuiparser.cpp | 511 ++++++++++++++++++++++++++++++++++++----- indra/llxuixml/llxuiparser.h | 86 +++++-- 3 files changed, 532 insertions(+), 78 deletions(-) (limited to 'indra/llxuixml') diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index b645c4be7c..1cc7d06b73 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -40,6 +40,7 @@ f * @file llinitparam.h #include #include #include +#include #include "llregistry.h" #include "llmemory.h" @@ -202,13 +203,13 @@ namespace LLInitParam typedef std::pair name_stack_range_t; typedef std::vector possible_values_t; - typedef boost::function parser_read_func_t; + typedef bool (*parser_read_func_t)(Parser& parser, void* output); typedef boost::function parser_write_func_t; typedef boost::function parser_inspect_func_t; - typedef std::map parser_read_func_map_t; - typedef std::map parser_write_func_map_t; - typedef std::map parser_inspect_func_map_t; + typedef boost::unordered_map parser_read_func_map_t; + typedef boost::unordered_map parser_write_func_map_t; + typedef boost::unordered_map parser_inspect_func_map_t; Parser() : mParseSilently(false), @@ -221,7 +222,7 @@ namespace LLInitParam parser_read_func_map_t::iterator found_it = mParserReadFuncs.find(&typeid(T)); if (found_it != mParserReadFuncs.end()) { - return found_it->second((void*)¶m); + return found_it->second(*this, (void*)¶m); } return false; } @@ -386,7 +387,7 @@ namespace LLInitParam void aggregateBlockData(BlockDescriptor& src_block_data); public: - typedef std::map param_map_t; // references param descriptors stored in mAllParams + typedef boost::unordered_map param_map_t; // references param descriptors stored in mAllParams typedef std::vector param_list_t; typedef std::list all_params_list_t;// references param descriptors stored in mAllParams 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 diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h index 884f4f7578..4deb083e1c 100644 --- a/indra/llxuixml/llxuiparser.h +++ b/indra/llxuixml/llxuiparser.h @@ -120,26 +120,24 @@ public: void writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const LLInitParam::BaseBlock* diff_block = NULL); private: - typedef std::list > token_list_t; - bool readXUIImpl(LLXMLNodePtr node, const std::string& scope, LLInitParam::BaseBlock& block); bool readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block); //reader helper functions - bool readBoolValue(void* val_ptr); - bool readStringValue(void* val_ptr); - bool readU8Value(void* val_ptr); - bool readS8Value(void* val_ptr); - bool readU16Value(void* val_ptr); - bool readS16Value(void* val_ptr); - bool readU32Value(void* val_ptr); - bool readS32Value(void* val_ptr); - bool readF32Value(void* val_ptr); - bool readF64Value(void* val_ptr); - bool readColor4Value(void* val_ptr); - bool readUIColorValue(void* val_ptr); - bool readUUIDValue(void* val_ptr); - bool readSDValue(void* val_ptr); + static bool readBoolValue(Parser& parser, void* val_ptr); + static bool readStringValue(Parser& parser, void* val_ptr); + static bool readU8Value(Parser& parser, void* val_ptr); + static bool readS8Value(Parser& parser, void* val_ptr); + static bool readU16Value(Parser& parser, void* val_ptr); + static bool readS16Value(Parser& parser, void* val_ptr); + static bool readU32Value(Parser& parser, void* val_ptr); + static bool readS32Value(Parser& parser, void* val_ptr); + static bool readF32Value(Parser& parser, void* val_ptr); + static bool readF64Value(Parser& parser, void* val_ptr); + static bool readColor4Value(Parser& parser, void* val_ptr); + static bool readUIColorValue(Parser& parser, void* val_ptr); + static bool readUUIDValue(Parser& parser, void* val_ptr); + static bool readSDValue(Parser& parser, void* val_ptr); //writer helper functions bool writeBoolValue(const void* val_ptr, const name_stack_t&); @@ -173,5 +171,61 @@ private: std::string mCurFileName; }; +class LLFastXUIParser : public LLInitParam::Parser, public LLSingleton +{ +LOG_CLASS(LLFastXUIParser); + +protected: + LLFastXUIParser(); + virtual ~LLFastXUIParser(); + friend class LLSingleton; +public: + typedef LLInitParam::Parser::name_stack_t name_stack_t; + + /*virtual*/ std::string getCurrentElementName(); + /*virtual*/ void parserWarning(const std::string& message); + /*virtual*/ void parserError(const std::string& message); + + bool readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent=false); + +private: + //reader helper functions + static bool readBoolValue(Parser&, void* val_ptr); + static bool readStringValue(Parser&, void* val_ptr); + static bool readU8Value(Parser&, void* val_ptr); + static bool readS8Value(Parser&, void* val_ptr); + static bool readU16Value(Parser&, void* val_ptr); + static bool readS16Value(Parser&, void* val_ptr); + static bool readU32Value(Parser&, void* val_ptr); + static bool readS32Value(Parser&, void* val_ptr); + static bool readF32Value(Parser&, void* val_ptr); + static bool readF64Value(Parser&, void* val_ptr); + static bool readColor4Value(Parser&, void* val_ptr); + static bool readUIColorValue(Parser&, void* val_ptr); + static bool readUUIDValue(Parser&, void* val_ptr); + static bool readSDValue(Parser&, void* val_ptr); + +private: + static void startElementHandler(void *userData, const char *name, const char **atts); + static void endElementHandler(void *userData, const char *name); + static void characterDataHandler(void *userData, const char *s, int len); + + void startElement(const char *name, const char **atts); + void endElement(const char *name); + void characterData(const char *s, int len); + bool readAttributes(const char **atts); + + LLInitParam::BaseBlock* mBlock; + Parser::name_stack_t mNameStack; + struct XML_ParserStruct* mParser; + S32 mLastWriteGeneration; + LLXMLNodePtr mLastWrittenChild; + S32 mCurReadDepth; + std::string mCurFileName; + const char* mCurAttributeValueBegin; + std::vector mTokenSizeStack; + std::vector mScope; +}; + #endif //LLXUIPARSER_H -- cgit v1.2.3 From 52936c4ffe97172a5d4926e252f2a25515c47895 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 5 Aug 2010 13:15:22 -0700 Subject: reverted unportable use of typeinfo* as hash key --- indra/llxuixml/llinitparam.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/llxuixml') diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index 1cc7d06b73..9890bacea4 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -207,9 +207,9 @@ namespace LLInitParam typedef boost::function parser_write_func_t; typedef boost::function parser_inspect_func_t; - typedef boost::unordered_map parser_read_func_map_t; - typedef boost::unordered_map parser_write_func_map_t; - typedef boost::unordered_map parser_inspect_func_map_t; + typedef std::map parser_read_func_map_t; + typedef std::map parser_write_func_map_t; + typedef std::map parser_inspect_func_map_t; Parser() : mParseSilently(false), -- 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') 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') 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 ++++++++++++++++++++++------------------- indra/llxuixml/llxuiparser.h | 23 +++++++-- 2 files changed, 77 insertions(+), 54 deletions(-) (limited to 'indra/llxuixml') 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 diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h index 4deb083e1c..eb7147f49e 100644 --- a/indra/llxuixml/llxuiparser.h +++ b/indra/llxuixml/llxuiparser.h @@ -171,14 +171,25 @@ private: std::string mCurFileName; }; -class LLFastXUIParser : public LLInitParam::Parser, public LLSingleton +// LLSimpleXUIParser is a streamlined SAX-based XUI parser that does not support localization +// or parsing of a tree of independent param blocks, such as child widgets. +// Use this for reading non-localized files that only need a single param block as a result. +// +// NOTE: In order to support nested block parsing, we need callbacks for start element that +// push new blocks contexts on the mScope stack. +// NOTE: To support localization without building a DOM, we need to enforce consistent +// ordering of child elements from base file to localized diff file. Then we can use a pair +// of coroutines to perform matching of xml nodes during parsing. Not sure if the overhead +// of coroutines would offset the gain from SAX parsing + +class LLSimpleXUIParser : public LLInitParam::Parser, public LLSingleton { -LOG_CLASS(LLFastXUIParser); +LOG_CLASS(LLSimpleXUIParser); protected: - LLFastXUIParser(); - virtual ~LLFastXUIParser(); - friend class LLSingleton; + LLSimpleXUIParser(); + virtual ~LLSimpleXUIParser(); + friend class LLSingleton; public: typedef LLInitParam::Parser::name_stack_t name_stack_t; @@ -187,6 +198,7 @@ public: /*virtual*/ void parserError(const std::string& message); bool readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent=false); + void setBlock(LLInitParam::BaseBlock* block); private: //reader helper functions @@ -222,6 +234,7 @@ private: LLXMLNodePtr mLastWrittenChild; S32 mCurReadDepth; std::string mCurFileName; + std::string mTextContents; const char* mCurAttributeValueBegin; std::vector mTokenSizeStack; std::vector mScope; -- 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') 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 720b29b1b42fb16ecff835bc1a103bc66499ab94 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Mon, 16 Aug 2010 14:58:31 -0700 Subject: added ability to replace existing entries in a LLRegistry --- indra/llxuixml/llregistry.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/llxuixml') diff --git a/indra/llxuixml/llregistry.h b/indra/llxuixml/llregistry.h index 2c04d8c419..53d4ac8e34 100644 --- a/indra/llxuixml/llregistry.h +++ b/indra/llxuixml/llregistry.h @@ -76,6 +76,11 @@ public: mMap.erase(key); } + void replace(ref_const_key_t key, ref_const_value_t value) + { + mMap[key] = value; + } + typename registry_map_t::const_iterator beginItems() const { return mMap.begin(); -- cgit v1.2.3 From 1fe2cb24f4288840fd682cae8274c193d66a1886 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Mon, 16 Aug 2010 14:59:06 -0700 Subject: fixed slicing problem with paramblocks where block descriptors are invalid after copying a derived block type to a base block value. --- indra/llxuixml/llinitparam.cpp | 5 +---- indra/llxuixml/llinitparam.h | 13 +++++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'indra/llxuixml') diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp index 8d6aa405e2..99191d2dbe 100644 --- a/indra/llxuixml/llinitparam.cpp +++ b/indra/llxuixml/llinitparam.cpp @@ -84,8 +84,7 @@ namespace LLInitParam // BaseBlock // BaseBlock::BaseBlock() - : mChangeVersion(0), - mBlockDescriptor(NULL) + : mChangeVersion(0) {} BaseBlock::~BaseBlock() @@ -94,8 +93,6 @@ namespace LLInitParam // called by each derived class in least to most derived order void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size) { - mBlockDescriptor = &descriptor; - descriptor.mCurrentBlockPtr = this; descriptor.mMaxParamOffset = block_size; diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index 9890bacea4..5461ad9d05 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -480,8 +480,8 @@ namespace LLInitParam bool serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const; bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t()) const; - const BlockDescriptor& mostDerivedBlockDescriptor() const { return *mBlockDescriptor; } - BlockDescriptor& mostDerivedBlockDescriptor() { return *mBlockDescriptor; } + virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } + virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); } // take all provided params from other and apply to self bool overwriteFrom(const BaseBlock& other) @@ -506,8 +506,6 @@ namespace LLInitParam // can be updated in getters mutable S32 mChangeVersion; - BlockDescriptor* mBlockDescriptor; // most derived block descriptor - static BlockDescriptor& selfBlockDescriptor() { static BlockDescriptor sBlockDescriptor; @@ -1313,6 +1311,9 @@ namespace LLInitParam BaseBlock::setLastChangedParam(last_param, user_provided); } + virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } + virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); } + protected: Choice() : mCurChoice(0) @@ -1422,6 +1423,10 @@ namespace LLInitParam { return BaseBlock::merge(selfBlockDescriptor(), other, false); } + + virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } + virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); } + protected: Block() { -- cgit v1.2.3 From bc12956a304c0c9c8d67a86a4e6d2e108026c169 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 19 Aug 2010 13:59:46 -0700 Subject: Fix for bad accelerator string lookups --- indra/llxuixml/lltrans.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'indra/llxuixml') diff --git a/indra/llxuixml/lltrans.h b/indra/llxuixml/lltrans.h index 6c8d28b346..30c96f8121 100644 --- a/indra/llxuixml/lltrans.h +++ b/indra/llxuixml/lltrans.h @@ -107,7 +107,16 @@ public: { std::string key_str(keystring); std::string trans_str; - return findString(trans_str, "Key_" + key_str) ? trans_str : key_str; + if (findString(trans_str, "Key_" + key_str)) + { + return trans_str; + } + else if (findString(trans_str, key_str)) + { + return trans_str; + } + llwarns << "Failed to find keyboard string " << keystring << llendl; + return key_str; } // get the default args -- cgit v1.2.3 From 48e0087ce3096e3ebe778124cdb21b87eedcc07c Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 19 Aug 2010 15:29:09 -0700 Subject: removed keyboarstring spam --- indra/llxuixml/lltrans.h | 1 - 1 file changed, 1 deletion(-) (limited to 'indra/llxuixml') diff --git a/indra/llxuixml/lltrans.h b/indra/llxuixml/lltrans.h index 30c96f8121..4a99c5e0e2 100644 --- a/indra/llxuixml/lltrans.h +++ b/indra/llxuixml/lltrans.h @@ -115,7 +115,6 @@ public: { return trans_str; } - llwarns << "Failed to find keyboard string " << keystring << llendl; return key_str; } -- 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/llinitparam.h | 65 +++++++------ indra/llxuixml/lltrans.cpp | 6 +- indra/llxuixml/llxuiparser.cpp | 202 +++++++++++++++++++++++++---------------- indra/llxuixml/llxuiparser.h | 51 +++++------ 4 files changed, 187 insertions(+), 137 deletions(-) (limited to 'indra/llxuixml') diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index 5461ad9d05..488e20cf9f 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -204,14 +204,14 @@ namespace LLInitParam typedef std::vector possible_values_t; typedef bool (*parser_read_func_t)(Parser& parser, void* output); - typedef boost::function parser_write_func_t; + typedef bool (*parser_write_func_t)(Parser& parser, const void*, const name_stack_t&); typedef boost::function parser_inspect_func_t; typedef std::map parser_read_func_map_t; typedef std::map parser_write_func_map_t; typedef std::map parser_inspect_func_map_t; - Parser() + Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map) : mParseSilently(false), mParseGeneration(0) {} @@ -219,8 +219,8 @@ namespace LLInitParam template bool readValue(T& param) { - parser_read_func_map_t::iterator found_it = mParserReadFuncs.find(&typeid(T)); - if (found_it != mParserReadFuncs.end()) + parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T)); + if (found_it != mParserReadFuncs->end()) { return found_it->second(*this, (void*)¶m); } @@ -229,10 +229,10 @@ namespace LLInitParam template bool writeValue(const T& param, const name_stack_t& name_stack) { - parser_write_func_map_t::iterator found_it = mParserWriteFuncs.find(&typeid(T)); - if (found_it != mParserWriteFuncs.end()) + parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T)); + if (found_it != mParserWriteFuncs->end()) { - return found_it->second((const void*)¶m, name_stack); + return found_it->second(*this, (const void*)¶m, name_stack); } return false; } @@ -240,8 +240,8 @@ namespace LLInitParam // dispatch inspection to registered inspection functions, for each parameter in a param block template bool inspectValue(const name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values) { - parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs.find(&typeid(T)); - if (found_it != mParserInspectFuncs.end()) + parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs->find(&typeid(T)); + if (found_it != mParserInspectFuncs->end()) { found_it->second(name_stack, min_count, max_count, possible_values); return true; @@ -253,7 +253,6 @@ namespace LLInitParam virtual void parserWarning(const std::string& message); virtual void parserError(const std::string& message); void setParseSilently(bool silent) { mParseSilently = silent; } - bool getParseSilently() { return mParseSilently; } S32 getParseGeneration() { return mParseGeneration; } S32 newParseGeneration() { return ++mParseGeneration; } @@ -261,24 +260,24 @@ namespace LLInitParam protected: template - void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func) + void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func = NULL) { - mParserReadFuncs.insert(std::make_pair(&typeid(T), read_func)); - mParserWriteFuncs.insert(std::make_pair(&typeid(T), write_func)); + mParserReadFuncs->insert(std::make_pair(&typeid(T), read_func)); + mParserWriteFuncs->insert(std::make_pair(&typeid(T), write_func)); } template void registerInspectFunc(parser_inspect_func_t inspect_func) { - mParserInspectFuncs.insert(std::make_pair(&typeid(T), inspect_func)); + mParserInspectFuncs->insert(std::make_pair(&typeid(T), inspect_func)); } bool mParseSilently; private: - parser_read_func_map_t mParserReadFuncs; - parser_write_func_map_t mParserWriteFuncs; - parser_inspect_func_map_t mParserInspectFuncs; + parser_read_func_map_t* mParserReadFuncs; + parser_write_func_map_t* mParserWriteFuncs; + parser_inspect_func_map_t* mParserInspectFuncs; S32 mParseGeneration; }; @@ -581,7 +580,7 @@ namespace LLInitParam // no further names in stack, attempt to parse value now if (name_stack.first == name_stack.second) { - if (parser.readValue(typed_param.mData.mValue)) + if (parser.readValue(typed_param.mData.mValue)) { typed_param.mData.clearKey(); typed_param.setProvided(true); @@ -594,7 +593,7 @@ namespace LLInitParam { // try to parse a known named value std::string name; - if (parser.readValue(name)) + if (parser.readValue(name)) { // try to parse a per type named value if (NAME_VALUE_LOOKUP::get(name, typed_param.mData.mValue)) @@ -629,7 +628,7 @@ namespace LLInitParam { if (!diff_param || !ParamCompare::equals(static_cast(diff_param)->mData.getKey(), key)) { - if (!parser.writeValue(key, name_stack)) + if (!parser.writeValue(key, name_stack)) { return; } @@ -637,7 +636,7 @@ namespace LLInitParam } // then try to serialize value directly else if (!diff_param || !ParamCompare::equals(typed_param.get(), static_cast(diff_param)->get())) { - if (!parser.writeValue(typed_param.mData.mValue, name_stack)) + if (!parser.writeValue(typed_param.mData.mValue, name_stack)) { return; } @@ -750,7 +749,7 @@ namespace LLInitParam { // try to parse a known named value std::string name; - if (parser.readValue(name)) + if (parser.readValue(name)) { // try to parse a per type named value if (NAME_VALUE_LOOKUP::get(name, typed_param)) @@ -777,7 +776,7 @@ namespace LLInitParam std::string key = typed_param.mData.getKey(); if (!key.empty() && typed_param.mData.mKeyVersion == typed_param.getLastChangeVersion()) { - if (!parser.writeValue(key, name_stack)) + if (!parser.writeValue(key, name_stack)) { return; } @@ -924,7 +923,7 @@ namespace LLInitParam if (name_stack.first == name_stack.second) { // attempt to read value directly - if (parser.readValue(value)) + if (parser.readValue(value)) { typed_param.mValues.push_back(value); // save an empty name/value key as a placeholder @@ -939,7 +938,7 @@ namespace LLInitParam { // try to parse a known named value std::string name; - if (parser.readValue(name)) + if (parser.readValue(name)) { // try to parse a per type named value if (NAME_VALUE_LOOKUP::get(name, typed_param.mValues)) @@ -973,13 +972,13 @@ namespace LLInitParam if(!key.empty()) { - if(!parser.writeValue(key, name_stack)) + if(!parser.writeValue(key, name_stack)) { return; } } // not parse via name values, write out value directly - else if (!parser.writeValue(*it, name_stack)) + else if (!parser.writeValue(*it, name_stack)) { return; } @@ -1126,7 +1125,7 @@ namespace LLInitParam { // try to parse a known named value std::string name; - if (parser.readValue(name)) + if (parser.readValue(name)) { // try to parse a per type named value if (NAME_VALUE_LOOKUP::get(name, value)) @@ -1159,7 +1158,7 @@ namespace LLInitParam std::string key = key_it->getKey(); if (!key.empty() && key_it->mKeyVersion == it->getLastChangeVersion()) { - if(!parser.writeValue(key, name_stack)) + if(!parser.writeValue(key, name_stack)) { return; } @@ -1624,7 +1623,7 @@ namespace LLInitParam // type to apply parse direct value T if (name_stack.first == name_stack.second) { - if(parser.readValue(typed_param.mData.mValue)) + if(parser.readValue(typed_param.mData.mValue)) { typed_param.enclosingBlock().setLastChangedParam(param, true); typed_param.setProvided(true); @@ -1639,7 +1638,7 @@ namespace LLInitParam { // try to parse a known named value std::string name; - if (parser.readValue(name)) + if (parser.readValue(name)) { // try to parse a per type named value if (TypeValues::get(name, typed_param.mData.mValue)) @@ -1681,7 +1680,7 @@ namespace LLInitParam { if (!diff_param || !ParamCompare::equals(static_cast(diff_param)->mData.getKey(), key)) { - if (!parser.writeValue(key, name_stack)) + if (!parser.writeValue(key, name_stack)) { return; } @@ -1691,7 +1690,7 @@ namespace LLInitParam else if (!diff_param || !ParamCompare::equals(typed_param.get(), (static_cast(diff_param))->get())) { - if (parser.writeValue(typed_param.mData.mValue, name_stack)) + if (parser.writeValue(typed_param.mData.mValue, name_stack)) { return; } diff --git a/indra/llxuixml/lltrans.cpp b/indra/llxuixml/lltrans.cpp index d6f17dbb08..bf38e925c6 100644 --- a/indra/llxuixml/lltrans.cpp +++ b/indra/llxuixml/lltrans.cpp @@ -72,7 +72,8 @@ bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set& defa } StringTable string_table; - LLXUIParser::instance().readXUI(root, string_table, xml_filename); + LLXUIParser parser; + parser.readXUI(root, string_table, xml_filename); if (!string_table.validateBlock()) { @@ -115,7 +116,8 @@ bool LLTrans::parseLanguageStrings(LLXMLNodePtr &root) } StringTable string_table; - LLXUIParser::instance().readXUI(root, string_table, xml_filename); + LLXUIParser parser; + parser.readXUI(root, string_table, xml_filename); if (!string_table.validateBlock()) { 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) diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h index eb7147f49e..ee8fcdc369 100644 --- a/indra/llxuixml/llxuiparser.h +++ b/indra/llxuixml/llxuiparser.h @@ -102,14 +102,12 @@ public: -class LLXUIParser : public LLInitParam::Parser, public LLSingleton +class LLXUIParser : public LLInitParam::Parser { LOG_CLASS(LLXUIParser); -protected: - LLXUIParser(); - friend class LLSingleton; public: + LLXUIParser(); typedef LLInitParam::Parser::name_stack_t name_stack_t; /*virtual*/ std::string getCurrentElementName(); @@ -140,20 +138,20 @@ private: static bool readSDValue(Parser& parser, void* val_ptr); //writer helper functions - bool writeBoolValue(const void* val_ptr, const name_stack_t&); - bool writeStringValue(const void* val_ptr, const name_stack_t&); - bool writeU8Value(const void* val_ptr, const name_stack_t&); - bool writeS8Value(const void* val_ptr, const name_stack_t&); - bool writeU16Value(const void* val_ptr, const name_stack_t&); - bool writeS16Value(const void* val_ptr, const name_stack_t&); - bool writeU32Value(const void* val_ptr, const name_stack_t&); - bool writeS32Value(const void* val_ptr, const name_stack_t&); - bool writeF32Value(const void* val_ptr, const name_stack_t&); - bool writeF64Value(const void* val_ptr, const name_stack_t&); - bool writeColor4Value(const void* val_ptr, const name_stack_t&); - bool writeUIColorValue(const void* val_ptr, const name_stack_t&); - bool writeUUIDValue(const void* val_ptr, const name_stack_t&); - bool writeSDValue(const void* val_ptr, const name_stack_t&); + static bool writeBoolValue(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeStringValue(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeU8Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeS8Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeU16Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeS16Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeU32Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeS32Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeF32Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeF64Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeColor4Value(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeUIColorValue(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeUUIDValue(Parser& parser, const void* val_ptr, const name_stack_t&); + static bool writeSDValue(Parser& parser, const void* val_ptr, const name_stack_t&); LLXMLNodePtr getNode(const name_stack_t& stack); @@ -182,23 +180,22 @@ private: // of coroutines to perform matching of xml nodes during parsing. Not sure if the overhead // of coroutines would offset the gain from SAX parsing -class LLSimpleXUIParser : public LLInitParam::Parser, public LLSingleton +class LLSimpleXUIParser : public LLInitParam::Parser { LOG_CLASS(LLSimpleXUIParser); - -protected: - LLSimpleXUIParser(); - virtual ~LLSimpleXUIParser(); - friend class LLSingleton; public: typedef LLInitParam::Parser::name_stack_t name_stack_t; + typedef LLInitParam::BaseBlock* (*element_start_callback_t)(LLSimpleXUIParser&, const char* block_name); + + LLSimpleXUIParser(element_start_callback_t element_cb = NULL); + virtual ~LLSimpleXUIParser(); /*virtual*/ std::string getCurrentElementName(); /*virtual*/ void parserWarning(const std::string& message); /*virtual*/ void parserError(const std::string& message); bool readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent=false); - void setBlock(LLInitParam::BaseBlock* block); + private: //reader helper functions @@ -227,7 +224,6 @@ private: void characterData(const char *s, int len); bool readAttributes(const char **atts); - LLInitParam::BaseBlock* mBlock; Parser::name_stack_t mNameStack; struct XML_ParserStruct* mParser; S32 mLastWriteGeneration; @@ -238,6 +234,9 @@ private: const char* mCurAttributeValueBegin; std::vector mTokenSizeStack; std::vector mScope; + element_start_callback_t mElementCB; + + std::vector > mOutputStack; }; -- 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/llinitparam.cpp | 44 +++--------------------------------------- indra/llxuixml/llinitparam.h | 6 ++++-- indra/llxuixml/llxuiparser.cpp | 17 ++++++++++++---- indra/llxuixml/llxuiparser.h | 3 ++- 4 files changed, 22 insertions(+), 48 deletions(-) (limited to 'indra/llxuixml') diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp index 99191d2dbe..922a91b609 100644 --- a/indra/llxuixml/llinitparam.cpp +++ b/indra/llxuixml/llinitparam.cpp @@ -74,7 +74,6 @@ namespace LLInitParam void BlockDescriptor::aggregateBlockData(BlockDescriptor& src_block_data) { mNamedParams.insert(src_block_data.mNamedParams.begin(), src_block_data.mNamedParams.end()); - mSynonyms.insert(src_block_data.mSynonyms.begin(), src_block_data.mSynonyms.end()); std::copy(src_block_data.mUnnamedParams.begin(), src_block_data.mUnnamedParams.end(), std::back_inserter(mUnnamedParams)); std::copy(src_block_data.mValidationList.begin(), src_block_data.mValidationList.end(), std::back_inserter(mValidationList)); std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams)); @@ -277,22 +276,6 @@ namespace LLInitParam } } - for(BlockDescriptor::param_map_t::const_iterator it = block_data.mSynonyms.begin(); - it != block_data.mSynonyms.end(); - ++it) - { - param_handle_t param_handle = it->second->mParamHandle; - const Param* param = getParamFromHandle(param_handle); - ParamDescriptor::inspect_func_t inspect_func = it->second->mInspectFunc; - if (inspect_func) - { - // use existing serial number for param - name_stack.push_back(std::make_pair(it->first, it->second->mGeneration)); - inspect_func(*param, parser, name_stack, it->second->mMinCount, it->second->mMaxCount); - name_stack.pop_back(); - } - } - return true; } @@ -314,22 +297,9 @@ namespace LLInitParam // find pointer to member parameter from offset table paramp = getParamFromHandle(found_it->second->mParamHandle); deserialize_func = found_it->second->mDeserializeFunc; - } - else - { - BlockDescriptor::param_map_t::iterator found_it = block_data.mSynonyms.find(top_name); - if (found_it != block_data.mSynonyms.end()) - { - // find pointer to member parameter from offset table - paramp = getParamFromHandle(found_it->second->mParamHandle); - deserialize_func = found_it->second->mDeserializeFunc; - } - } - Parser::name_stack_range_t new_name_stack(name_stack.first, name_stack.second); - ++new_name_stack.first; - if (deserialize_func) - { + Parser::name_stack_range_t new_name_stack(name_stack.first, name_stack.second); + ++new_name_stack.first; return deserialize_func(*paramp, p, new_name_stack, name_stack.first == name_stack.second ? -1 : name_stack.first->second); } } @@ -404,7 +374,7 @@ namespace LLInitParam } else { - block_data.mSynonyms[synonym] = param_descriptor; + block_data.mNamedParams[synonym] = param_descriptor; } } } @@ -429,14 +399,6 @@ namespace LLInitParam } } - for (BlockDescriptor::param_map_t::const_iterator it = block_data.mSynonyms.begin(); it != block_data.mSynonyms.end(); ++it) - { - if (it->second->mParamHandle == handle) - { - return it->first; - } - } - return LLStringUtil::null; } diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index 488e20cf9f..51dbd99fb1 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -213,7 +213,10 @@ namespace LLInitParam Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map) : mParseSilently(false), - mParseGeneration(0) + mParseGeneration(0), + mParserReadFuncs(&read_map), + mParserWriteFuncs(&write_map), + mParserInspectFuncs(&inspect_map) {} virtual ~Parser(); @@ -393,7 +396,6 @@ namespace LLInitParam typedef std::vector > param_validation_list_t; param_map_t mNamedParams; // parameters with associated names - param_map_t mSynonyms; // parameters with alternate names param_list_t mUnnamedParams; // parameters with_out_ associated names param_validation_list_t mValidationList; // parameters that must be validated all_params_list_t mAllParams; // all parameters, owns descriptors 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 diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h index ee8fcdc369..1a4a7c49d1 100644 --- a/indra/llxuixml/llxuiparser.h +++ b/indra/llxuixml/llxuiparser.h @@ -118,7 +118,7 @@ public: void writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const LLInitParam::BaseBlock* diff_block = NULL); private: - bool readXUIImpl(LLXMLNodePtr node, const std::string& scope, LLInitParam::BaseBlock& block); + bool readXUIImpl(LLXMLNodePtr node, LLInitParam::BaseBlock& block); bool readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block); //reader helper functions @@ -167,6 +167,7 @@ private: LLXMLNodePtr mLastWrittenChild; S32 mCurReadDepth; std::string mCurFileName; + std::string mRootNodeName; }; // LLSimpleXUIParser is a streamlined SAX-based XUI parser that does not support localization -- cgit v1.2.3