bool CGUIWindow::Load(TiXmlElement* pRootElement) { if (!pRootElement) return false; if (strcmpi(pRootElement->Value(), "window")) { CLog::Log(LOGERROR, "file : XML file doesnt contain <window>"); return false; } // we must create copy of root element as we will manipulate it when resolving includes // and we don't want original root element to change pRootElement = (TiXmlElement*)pRootElement->Clone(); // set the scaling resolution so that any control creation or initialisation can // be done with respect to the correct aspect ratio g_graphicsContext.SetScalingResolution(m_coordsRes, m_needsScaling); // Resolve any includes that may be present and save conditions used to do it g_SkinInfo->ResolveIncludes(pRootElement, &m_xmlIncludeConditions); // now load in the skin file SetDefaults(); CGUIControlFactory::GetInfoColor(pRootElement, "backgroundcolor", m_clearBackground, GetID()); CGUIControlFactory::GetActions(pRootElement, "onload", m_loadActions); CGUIControlFactory::GetActions(pRootElement, "onunload", m_unloadActions); CGUIControlFactory::GetHitRect(pRootElement, m_hitRect); TiXmlElement *pChild = pRootElement->FirstChildElement(); while (pChild) { std::string strValue = pChild->Value(); if (strValue == "type" && pChild->FirstChild()) { // if we have are a window type (ie not a dialog), and we have <type>dialog</type> // then make this window act like a dialog if (!IsDialog() && strcmpi(pChild->FirstChild()->Value(), "dialog") == 0) m_isDialog = true; } else if (strValue == "previouswindow" && pChild->FirstChild()) { m_previousWindow = CButtonTranslator::TranslateWindow(pChild->FirstChild()->Value()); } else if (strValue == "defaultcontrol" && pChild->FirstChild()) { const char *always = pChild->Attribute("always"); if (always && strcmpi(always, "true") == 0) m_defaultAlways = true; m_defaultControl = atoi(pChild->FirstChild()->Value()); } else if(strValue == "menucontrol" && pChild->FirstChild()) { m_menuControlID = atoi(pChild->FirstChild()->Value()); } else if (strValue == "visible" && pChild->FirstChild()) { std::string condition; CGUIControlFactory::GetConditionalVisibility(pRootElement, condition); m_visibleCondition = g_infoManager.Register(condition, GetID()); } else if (strValue == "animation" && pChild->FirstChild()) { CRect rect(0, 0, (float)m_coordsRes.iWidth, (float)m_coordsRes.iHeight); CAnimation anim; anim.Create(pChild, rect, GetID()); m_animations.push_back(anim); } else if (strValue == "zorder" && pChild->FirstChild()) { m_renderOrder = atoi(pChild->FirstChild()->Value()); } else if (strValue == "coordinates") { XMLUtils::GetFloat(pChild, "posx", m_posX); XMLUtils::GetFloat(pChild, "posy", m_posY); XMLUtils::GetFloat(pChild, "left", m_posX); XMLUtils::GetFloat(pChild, "top", m_posY); TiXmlElement *originElement = pChild->FirstChildElement("origin"); while (originElement) { COrigin origin; originElement->QueryFloatAttribute("x", &origin.x); originElement->QueryFloatAttribute("y", &origin.y); if (originElement->FirstChild()) origin.condition = g_infoManager.Register(originElement->FirstChild()->Value(), GetID()); m_origins.push_back(origin); originElement = originElement->NextSiblingElement("origin"); } } else if (strValue == "camera") { // z is fixed pChild->QueryFloatAttribute("x", &m_camera.x); pChild->QueryFloatAttribute("y", &m_camera.y); m_hasCamera = true; } else if (strValue == "depth" && pChild->FirstChild()) { float stereo = (float)atof(pChild->FirstChild()->Value());; m_stereo = std::max(-1.f, std::min(1.f, stereo)); } else if (strValue == "controls") { TiXmlElement *pControl = pChild->FirstChildElement(); while (pControl) { if (strcmpi(pControl->Value(), "control") == 0) { LoadControl(pControl, NULL, CRect(0, 0, (float)m_coordsRes.iWidth, (float)m_coordsRes.iHeight)); } pControl = pControl->NextSiblingElement(); } } pChild = pChild->NextSiblingElement(); } LoadAdditionalTags(pRootElement); m_windowLoaded = true; OnWindowLoaded(); delete pRootElement; return true; }
void CButtonTranslator::MapWindowActions(TiXmlNode *pWindow, int windowID) { if (!pWindow || windowID == WINDOW_INVALID) return; TiXmlNode* pDevice; const char* types[] = {"gamepad", "remote", "universalremote", "keyboard", "mouse", "appcommand", NULL}; for (int i = 0; types[i]; ++i) { CStdString type(types[i]); if (HasDeviceType(pWindow, type)) { pDevice = pWindow->FirstChild(type); TiXmlElement *pDeviceElement = pDevice->ToElement(); CStdString deviceName; //check if exists, if not use "default" deviceName = pDeviceElement->Attribute("name"); if (deviceName.empty()) deviceName = "default"; std::map<CStdString, std::map<int, buttonMap> >::iterator deviceMapIt = deviceMappings.find(deviceName); if (deviceMapIt == deviceMappings.end()) { //First time encountering this device, lets initialise the buttonMap for it. deviceMapIt = deviceMappings.insert(pair<CStdString, std::map<int, buttonMap> >(deviceName, std::map<int, buttonMap>())).first; } std::map<int, buttonMap>::iterator windowIt = deviceMapIt->second.find(windowID); if (windowIt == deviceMapIt->second.end()) { //add it now windowIt = deviceMapIt->second.insert(pair<int, buttonMap>(windowID, buttonMap())).first; } buttonMap& windowMap = windowIt->second; TiXmlElement *pButton = pDevice->FirstChildElement(); while (pButton) { uint32_t buttonCode=0; if (type == "gamepad") buttonCode = TranslateGamepadString(pButton->Value()); else if (type == "remote") buttonCode = TranslateRemoteString(pButton->Value()); else if (type == "universalremote") buttonCode = TranslateUniversalRemoteString(pButton->Value()); else if (type == "keyboard") buttonCode = TranslateKeyboardButton(pButton); else if (type == "mouse") buttonCode = TranslateMouseCommand(pButton->Value()); else if (type == "appcommand") buttonCode = TranslateAppCommand(pButton->Value()); if (buttonCode && pButton->FirstChild()) MapAction(buttonCode, pButton->FirstChild()->Value(), windowMap); pButton = pButton->NextSiblingElement(); } } } #if defined(HAS_SDL_JOYSTICK) || defined(HAS_EVENT_SERVER) if ((pDevice = pWindow->FirstChild("joystick")) != NULL) { // map joystick actions while (pDevice) { MapJoystickActions(windowID, pDevice); pDevice = pDevice->NextSibling("joystick"); } } #endif }
void Map::ParseText(const string &text) { // Create a tiny xml document and use it to parse the text. TiXmlDocument doc; doc.Parse(text.c_str()); // Check for parsing errors. if (doc.Error()) { has_error = true; error_code = TMX_PARSING_ERROR; error_text = doc.ErrorDesc(); return; } TiXmlNode *mapNode = doc.FirstChild("map"); TiXmlElement* mapElem = mapNode->ToElement(); // Read the map attributes. mapElem->Attribute("version", &version); mapElem->Attribute("width", &width); mapElem->Attribute("height", &height); mapElem->Attribute("tilewidth", &tile_width); mapElem->Attribute("tileheight", &tile_height); // Read the orientation std::string orientationStr = mapElem->Attribute("orientation"); if (!orientationStr.compare("orthogonal")) { orientation = TMX_MO_ORTHOGONAL; } else if (!orientationStr.compare("isometric")) { orientation = TMX_MO_ISOMETRIC; } else if (!orientationStr.compare("staggered")) { orientation = TMX_MO_STAGGERED; } const TiXmlNode *node = mapElem->FirstChild(); int zOrder = 0; while( node ) { // Read the map properties. if( strcmp( node->Value(), "properties" ) == 0 ) { properties.Parse(node); } // Iterate through all of the tileset elements. if( strcmp( node->Value(), "tileset" ) == 0 ) { // Allocate a new tileset and parse it. Tileset *tileset = new Tileset(); tileset->Parse(node->ToElement()); // Add the tileset to the list. tilesets.push_back(tileset); } // Iterate through all of the layer elements. if( strcmp( node->Value(), "layer" ) == 0 ) { // Allocate a new layer and parse it. Layer *layer = new Layer(this); layer->Parse(node); layer->SetZOrder( zOrder ); ++zOrder; // Add the layer to the list. layers.push_back(layer); } // Iterate through all of the imagen layer elements. if( strcmp( node->Value(), "imagelayer" ) == 0 ) { // Allocate a new layer and parse it. ImageLayer *imageLayer = new ImageLayer(this); imageLayer->Parse(node); imageLayer->SetZOrder( zOrder ); ++zOrder; // Add the layer to the list. image_layers.push_back(imageLayer); } // Iterate through all of the objectgroup elements. if( strcmp( node->Value(), "objectgroup" ) == 0 ) { // Allocate a new object group and parse it. ObjectGroup *objectGroup = new ObjectGroup(); objectGroup->Parse(node); objectGroup->SetZOrder( zOrder ); ++zOrder; // Add the object group to the list. object_groups.push_back(objectGroup); } node = node->NextSibling(); } }
void CExternalPlayer::GetCustomRegexpReplacers(TiXmlElement *pRootElement, std::vector<std::string>& settings) { int iAction = 0; // overwrite // for backward compatibility const char* szAppend = pRootElement->Attribute("append"); if ((szAppend && stricmp(szAppend, "yes") == 0)) iAction = 1; // action takes precedence if both attributes exist const char* szAction = pRootElement->Attribute("action"); if (szAction) { iAction = 0; // overwrite if (stricmp(szAction, "append") == 0) iAction = 1; // append else if (stricmp(szAction, "prepend") == 0) iAction = 2; // prepend } if (iAction == 0) settings.clear(); TiXmlElement* pReplacer = pRootElement->FirstChildElement("replacer"); int i = 0; while (pReplacer) { if (pReplacer->FirstChild()) { const char* szGlobal = pReplacer->Attribute("global"); const char* szStop = pReplacer->Attribute("stop"); bool bGlobal = szGlobal && stricmp(szGlobal, "true") == 0; bool bStop = szStop && stricmp(szStop, "true") == 0; std::string strMatch; std::string strPat; std::string strRep; XMLUtils::GetString(pReplacer,"match",strMatch); XMLUtils::GetString(pReplacer,"pat",strPat); XMLUtils::GetString(pReplacer,"rep",strRep); if (!strPat.empty() && !strRep.empty()) { CLog::Log(LOGDEBUG," Registering replacer:"); CLog::Log(LOGDEBUG," Match:[%s] Pattern:[%s] Replacement:[%s]", strMatch.c_str(), strPat.c_str(), strRep.c_str()); CLog::Log(LOGDEBUG," Global:[%s] Stop:[%s]", bGlobal?"true":"false", bStop?"true":"false"); // keep literal commas since we use comma as a seperator StringUtils::Replace(strMatch, ",",",,"); StringUtils::Replace(strPat, ",",",,"); StringUtils::Replace(strRep, ",",",,"); std::string strReplacer = strMatch + " , " + strPat + " , " + strRep + " , " + (bGlobal ? "g" : "") + (bStop ? "s" : ""); if (iAction == 2) settings.insert(settings.begin() + i++, 1, strReplacer); else settings.push_back(strReplacer); } else { // error message about missing tag if (strPat.empty()) CLog::Log(LOGERROR," Missing <Pat> tag"); else CLog::Log(LOGERROR," Missing <Rep> tag"); } } pReplacer = pReplacer->NextSiblingElement("replacer"); } }
int main() { // // We start with the 'demoStart' todo list. Process it. And // should hopefully end up with the todo list as illustrated. // const char* demoStart = "<?xml version=\"1.0\" standalone='no' >\n" "<!-- Our to do list data -->" "<ToDo>\n" "<!-- Do I need a secure PDA? -->\n" "<Item priority=\"1\" distance='close'> Go to the <bold>Toy store!</bold></Item>" "<Item priority=\"2\" distance='none'> Do bills </Item>" "<Item priority=\"2\" distance='far & back'> Look for Evil Dinosaurs! </Item>" "</ToDo>"; { #ifdef TIXML_USE_STL /* What the todo list should look like after processing. In stream (no formatting) representation. */ const char* demoEnd = "<?xml version=\"1.0\" standalone=\"no\" ?>" "<!-- Our to do list data -->" "<ToDo>" "<!-- Do I need a secure PDA? -->" "<Item priority=\"2\" distance=\"close\">Go to the" "<bold>Toy store!" "</bold>" "</Item>" "<Item priority=\"1\" distance=\"far\">Talk to:" "<Meeting where=\"School\">" "<Attendee name=\"Marple\" position=\"teacher\" />" "<Attendee name=\"Voel\" position=\"counselor\" />" "</Meeting>" "<Meeting where=\"Lunch\" />" "</Item>" "<Item priority=\"2\" distance=\"here\">Do bills" "</Item>" "</ToDo>"; #endif // The example parses from the character string (above): #if defined( WIN32 ) && defined( TUNE ) _CrtMemCheckpoint( &startMemState ); #endif { // Write to a file and read it back, to check file I/O. TiXmlDocument doc( "demotest.xml" ); doc.Parse( demoStart ); if ( doc.Error() ) { printf( "Error in %s: %s\n", doc.Value(), doc.ErrorDesc() ); exit( 1 ); } doc.SaveFile(); } TiXmlDocument doc( "demotest.xml" ); bool loadOkay = doc.LoadFile(); if ( !loadOkay ) { printf( "Could not load test file 'demotest.xml'. Error='%s'. Exiting.\n", doc.ErrorDesc() ); exit( 1 ); } printf( "** Demo doc read from disk: ** \n\n" ); printf( "** Printing via doc.Print **\n" ); doc.Print( stdout ); { printf( "** Printing via TiXmlPrinter **\n" ); TiXmlPrinter printer; doc.Accept( &printer ); fprintf( stdout, "%s", printer.CStr() ); } #ifdef TIXML_USE_STL { printf( "** Printing via operator<< **\n" ); std::cout << doc; } #endif TiXmlNode* node = 0; TiXmlElement* todoElement = 0; TiXmlElement* itemElement = 0; // -------------------------------------------------------- // An example of changing existing attributes, and removing // an element from the document. // -------------------------------------------------------- // Get the "ToDo" element. // It is a child of the document, and can be selected by name. node = doc.FirstChild( "ToDo" ); assert( node ); todoElement = node->ToElement(); assert( todoElement ); // Going to the toy store is now our second priority... // So set the "priority" attribute of the first item in the list. node = todoElement->FirstChildElement(); // This skips the "PDA" comment. assert( node ); itemElement = node->ToElement(); assert( itemElement ); itemElement->SetAttribute( "priority", 2 ); // Change the distance to "doing bills" from // "none" to "here". It's the next sibling element. itemElement = itemElement->NextSiblingElement(); assert( itemElement ); itemElement->SetAttribute( "distance", "here" ); // Remove the "Look for Evil Dinosaurs!" item. // It is 1 more sibling away. We ask the parent to remove // a particular child. itemElement = itemElement->NextSiblingElement(); todoElement->RemoveChild( itemElement ); itemElement = 0; // -------------------------------------------------------- // What follows is an example of created elements and text // nodes and adding them to the document. // -------------------------------------------------------- // Add some meetings. TiXmlElement item( "Item" ); item.SetAttribute( "priority", "1" ); item.SetAttribute( "distance", "far" ); TiXmlText text( "Talk to:" ); TiXmlElement meeting1( "Meeting" ); meeting1.SetAttribute( "where", "School" ); TiXmlElement meeting2( "Meeting" ); meeting2.SetAttribute( "where", "Lunch" ); TiXmlElement attendee1( "Attendee" ); attendee1.SetAttribute( "name", "Marple" ); attendee1.SetAttribute( "position", "teacher" ); TiXmlElement attendee2( "Attendee" ); attendee2.SetAttribute( "name", "Voel" ); attendee2.SetAttribute( "position", "counselor" ); // Assemble the nodes we've created: meeting1.InsertEndChild( attendee1 ); meeting1.InsertEndChild( attendee2 ); item.InsertEndChild( text ); item.InsertEndChild( meeting1 ); item.InsertEndChild( meeting2 ); // And add the node to the existing list after the first child. node = todoElement->FirstChild( "Item" ); assert( node ); itemElement = node->ToElement(); assert( itemElement ); todoElement->InsertAfterChild( itemElement, item ); printf( "\n** Demo doc processed: ** \n\n" ); doc.Print( stdout ); #ifdef TIXML_USE_STL printf( "** Demo doc processed to stream: ** \n\n" ); cout << doc << endl << endl; #endif // -------------------------------------------------------- // Different tests...do we have what we expect? // -------------------------------------------------------- int count = 0; TiXmlElement* element; ////////////////////////////////////////////////////// #ifdef TIXML_USE_STL cout << "** Basic structure. **\n"; ostringstream outputStream( ostringstream::out ); outputStream << doc; XmlTest( "Output stream correct.", string( demoEnd ).c_str(), outputStream.str().c_str(), true ); #endif node = doc.RootElement(); assert( node ); XmlTest( "Root element exists.", true, ( node != 0 && node->ToElement() ) ); XmlTest ( "Root element value is 'ToDo'.", "ToDo", node->Value()); node = node->FirstChild(); XmlTest( "First child exists & is a comment.", true, ( node != 0 && node->ToComment() ) ); node = node->NextSibling(); XmlTest( "Sibling element exists & is an element.", true, ( node != 0 && node->ToElement() ) ); XmlTest ( "Value is 'Item'.", "Item", node->Value() ); node = node->FirstChild(); XmlTest ( "First child exists.", true, ( node != 0 && node->ToText() ) ); XmlTest ( "Value is 'Go to the'.", "Go to the", node->Value() ); ////////////////////////////////////////////////////// printf ("\n** Iterators. **\n"); // Walk all the top level nodes of the document. count = 0; for( node = doc.FirstChild(); node; node = node->NextSibling() ) { count++; } XmlTest( "Top level nodes, using First / Next.", 3, count ); count = 0; for( node = doc.LastChild(); node; node = node->PreviousSibling() ) { count++; } XmlTest( "Top level nodes, using Last / Previous.", 3, count ); // Walk all the top level nodes of the document, // using a different syntax. count = 0; for( node = doc.IterateChildren( 0 ); node; node = doc.IterateChildren( node ) ) { count++; } XmlTest( "Top level nodes, using IterateChildren.", 3, count ); // Walk all the elements in a node. count = 0; for( element = todoElement->FirstChildElement(); element; element = element->NextSiblingElement() ) { count++; } XmlTest( "Children of the 'ToDo' element, using First / Next.", 3, count ); // Walk all the elements in a node by value. count = 0; for( node = todoElement->FirstChild( "Item" ); node; node = node->NextSibling( "Item" ) ) { count++; } XmlTest( "'Item' children of the 'ToDo' element, using First/Next.", 3, count ); count = 0; for( node = todoElement->LastChild( "Item" ); node; node = node->PreviousSibling( "Item" ) ) { count++; } XmlTest( "'Item' children of the 'ToDo' element, using Last/Previous.", 3, count ); #ifdef TIXML_USE_STL { cout << "\n** Parsing. **\n"; istringstream parse0( "<Element0 attribute0='foo0' attribute1= noquotes attribute2 = '>' />" ); TiXmlElement element0( "default" ); parse0 >> element0; XmlTest ( "Element parsed, value is 'Element0'.", "Element0", element0.Value() ); XmlTest ( "Reads attribute 'attribute0=\"foo0\"'.", "foo0", element0.Attribute( "attribute0" )); XmlTest ( "Reads incorrectly formatted 'attribute1=noquotes'.", "noquotes", element0.Attribute( "attribute1" ) ); XmlTest ( "Read attribute with entity value '>'.", ">", element0.Attribute( "attribute2" ) ); } #endif { const char* error = "<?xml version=\"1.0\" standalone=\"no\" ?>\n" "<passages count=\"006\" formatversion=\"20020620\">\n" " <wrong error>\n" "</passages>"; TiXmlDocument docTest; docTest.Parse( error ); XmlTest( "Error row", docTest.ErrorRow(), 3 ); XmlTest( "Error column", docTest.ErrorCol(), 17 ); //printf( "error=%d id='%s' row %d col%d\n", (int) doc.Error(), doc.ErrorDesc(), doc.ErrorRow()+1, doc.ErrorCol() + 1 ); } #ifdef TIXML_USE_STL { ////////////////////////////////////////////////////// cout << "\n** Streaming. **\n"; // Round trip check: stream in, then stream back out to verify. The stream // out has already been checked, above. We use the output istringstream inputStringStream( outputStream.str() ); TiXmlDocument document0; inputStringStream >> document0; ostringstream outputStream0( ostringstream::out ); outputStream0 << document0; XmlTest( "Stream round trip correct.", string( demoEnd ).c_str(), outputStream0.str().c_str(), true ); std::string str; str << document0; XmlTest( "String printing correct.", string( demoEnd ).c_str(), str.c_str(), true ); } #endif } { const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />"; TiXmlDocument doc; doc.Parse( str ); TiXmlElement* ele = doc.FirstChildElement(); int iVal, result; double dVal; result = ele->QueryDoubleAttribute( "attr0", &dVal ); XmlTest( "Query attribute: int as double", result, TIXML_SUCCESS ); XmlTest( "Query attribute: int as double", (int)dVal, 1 ); result = ele->QueryDoubleAttribute( "attr1", &dVal ); XmlTest( "Query attribute: double as double", (int)dVal, 2 ); result = ele->QueryIntAttribute( "attr1", &iVal ); XmlTest( "Query attribute: double as int", result, TIXML_SUCCESS ); XmlTest( "Query attribute: double as int", iVal, 2 ); result = ele->QueryIntAttribute( "attr2", &iVal ); XmlTest( "Query attribute: not a number", result, TIXML_WRONG_TYPE ); result = ele->QueryIntAttribute( "bar", &iVal ); XmlTest( "Query attribute: does not exist", result, TIXML_NO_ATTRIBUTE ); } { const char* str = "\t<?xml version=\"1.0\" standalone=\"no\" ?>\t<room doors='2'>\n" "</room>"; TiXmlDocument doc; doc.SetTabSize( 8 ); doc.Parse( str ); TiXmlHandle docHandle( &doc ); TiXmlHandle roomHandle = docHandle.FirstChildElement( "room" ); assert( docHandle.Node() ); assert( roomHandle.Element() ); TiXmlElement* room = roomHandle.Element(); assert( room ); TiXmlAttribute* doors = room->FirstAttribute(); assert( doors ); XmlTest( "Location tracking: Tab 8: room row", room->Row(), 1 ); XmlTest( "Location tracking: Tab 8: room col", room->Column(), 49 ); XmlTest( "Location tracking: Tab 8: doors row", doors->Row(), 1 ); XmlTest( "Location tracking: Tab 8: doors col", doors->Column(), 55 ); } { const char* str = "\t<?xml version=\"1.0\" standalone=\"no\" ?>\t<room doors='2'>\n" " <!-- Silly example -->\n" " <door wall='north'>A great door!</door>\n" "\t<door wall='east'/>" "</room>"; TiXmlDocument doc; doc.Parse( str ); TiXmlHandle docHandle( &doc ); TiXmlHandle roomHandle = docHandle.FirstChildElement( "room" ); TiXmlHandle commentHandle = docHandle.FirstChildElement( "room" ).FirstChild(); TiXmlHandle textHandle = docHandle.FirstChildElement( "room" ).ChildElement( "door", 0 ).FirstChild(); TiXmlHandle door0Handle = docHandle.FirstChildElement( "room" ).ChildElement( 0 ); TiXmlHandle door1Handle = docHandle.FirstChildElement( "room" ).ChildElement( 1 ); assert( docHandle.Node() ); assert( roomHandle.Element() ); assert( commentHandle.Node() ); assert( textHandle.Text() ); assert( door0Handle.Element() ); assert( door1Handle.Element() ); TiXmlDeclaration* declaration = doc.FirstChild()->ToDeclaration(); assert( declaration ); TiXmlElement* room = roomHandle.Element(); assert( room ); TiXmlAttribute* doors = room->FirstAttribute(); assert( doors ); TiXmlText* text = textHandle.Text(); TiXmlComment* comment = commentHandle.Node()->ToComment(); assert( comment ); TiXmlElement* door0 = door0Handle.Element(); TiXmlElement* door1 = door1Handle.Element(); XmlTest( "Location tracking: Declaration row", declaration->Row(), 1 ); XmlTest( "Location tracking: Declaration col", declaration->Column(), 5 ); XmlTest( "Location tracking: room row", room->Row(), 1 ); XmlTest( "Location tracking: room col", room->Column(), 45 ); XmlTest( "Location tracking: doors row", doors->Row(), 1 ); XmlTest( "Location tracking: doors col", doors->Column(), 51 ); XmlTest( "Location tracking: Comment row", comment->Row(), 2 ); XmlTest( "Location tracking: Comment col", comment->Column(), 3 ); XmlTest( "Location tracking: text row", text->Row(), 3 ); XmlTest( "Location tracking: text col", text->Column(), 24 ); XmlTest( "Location tracking: door0 row", door0->Row(), 3 ); XmlTest( "Location tracking: door0 col", door0->Column(), 5 ); XmlTest( "Location tracking: door1 row", door1->Row(), 4 ); XmlTest( "Location tracking: door1 col", door1->Column(), 5 ); } // -------------------------------------------------------- // UTF-8 testing. It is important to test: // 1. Making sure name, value, and text read correctly // 2. Row, Col functionality // 3. Correct output // -------------------------------------------------------- printf ("\n** UTF-8 **\n"); { TiXmlDocument doc( "utf8test.xml" ); doc.LoadFile(); if ( doc.Error() && doc.ErrorId() == TiXmlBase::TIXML_ERROR_OPENING_FILE ) { printf( "WARNING: File 'utf8test.xml' not found.\n" "(Are you running the test from the wrong directory?)\n" "Could not test UTF-8 functionality.\n" ); } else { TiXmlHandle docH( &doc ); // Get the attribute "value" from the "Russian" element and check it. TiXmlElement* element = docH.FirstChildElement( "document" ).FirstChildElement( "Russian" ).Element(); const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU, 0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 }; XmlTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ), true ); XmlTest( "UTF-8: Russian value row.", 4, element->Row() ); XmlTest( "UTF-8: Russian value column.", 5, element->Column() ); const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U, 0xd1U, 0x81U, 0xd1U, 0x81U, 0xd0U, 0xbaU, 0xd0U, 0xb8U, 0xd0U, 0xb9U, 0 }; const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>"; TiXmlText* text = docH.FirstChildElement( "document" ).FirstChildElement( (const char*) russianElementName ).Child( 0 ).Text(); XmlTest( "UTF-8: Browsing russian element name.", russianText, text->Value(), true ); XmlTest( "UTF-8: Russian element name row.", 7, text->Row() ); XmlTest( "UTF-8: Russian element name column.", 47, text->Column() ); TiXmlDeclaration* dec = docH.Child( 0 ).Node()->ToDeclaration(); XmlTest( "UTF-8: Declaration column.", 1, dec->Column() ); XmlTest( "UTF-8: Document column.", 1, doc.Column() ); // Now try for a round trip. doc.SaveFile( "utf8testout.xml" ); // Check the round trip. char savedBuf[256]; char verifyBuf[256]; int okay = 1; FILE* saved = fopen( "utf8testout.xml", "r" ); FILE* verify = fopen( "utf8testverify.xml", "r" ); if ( saved && verify ) { while ( fgets( verifyBuf, 256, verify ) ) { fgets( savedBuf, 256, saved ); if ( strcmp( verifyBuf, savedBuf ) ) { okay = 0; break; } } fclose( saved ); fclose( verify ); } XmlTest( "UTF-8: Verified multi-language round trip.", 1, okay ); // On most Western machines, this is an element that contains // the word "resume" with the correct accents, in a latin encoding. // It will be something else completely on non-wester machines, // which is why TinyXml is switching to UTF-8. const char latin[] = "<element>r\x82sum\x82</element>"; TiXmlDocument latinDoc; latinDoc.Parse( latin, 0, TIXML_ENCODING_LEGACY ); text = latinDoc.FirstChildElement()->FirstChild()->ToText(); XmlTest( "Legacy encoding: Verify text element.", "r\x82sum\x82", text->Value() ); } } ////////////////////// // Copy and assignment ////////////////////// printf ("\n** Copy and Assignment **\n"); { TiXmlElement element( "foo" ); element.Parse( "<element name='value' />", 0, TIXML_ENCODING_UNKNOWN ); TiXmlElement elementCopy( element ); TiXmlElement elementAssign( "foo" ); elementAssign.Parse( "<incorrect foo='bar'/>", 0, TIXML_ENCODING_UNKNOWN ); elementAssign = element; XmlTest( "Copy/Assign: element copy #1.", "element", elementCopy.Value() ); XmlTest( "Copy/Assign: element copy #2.", "value", elementCopy.Attribute( "name" ) ); XmlTest( "Copy/Assign: element assign #1.", "element", elementAssign.Value() ); XmlTest( "Copy/Assign: element assign #2.", "value", elementAssign.Attribute( "name" ) ); XmlTest( "Copy/Assign: element assign #3.", true, ( 0 == elementAssign.Attribute( "foo" )) ); TiXmlComment comment; comment.Parse( "<!--comment-->", 0, TIXML_ENCODING_UNKNOWN ); TiXmlComment commentCopy( comment ); TiXmlComment commentAssign; commentAssign = commentCopy; XmlTest( "Copy/Assign: comment copy.", "comment", commentCopy.Value() ); XmlTest( "Copy/Assign: comment assign.", "comment", commentAssign.Value() ); TiXmlUnknown unknown; unknown.Parse( "<[unknown]>", 0, TIXML_ENCODING_UNKNOWN ); TiXmlUnknown unknownCopy( unknown ); TiXmlUnknown unknownAssign; unknownAssign.Parse( "incorrect", 0, TIXML_ENCODING_UNKNOWN ); unknownAssign = unknownCopy; XmlTest( "Copy/Assign: unknown copy.", "[unknown]", unknownCopy.Value() ); XmlTest( "Copy/Assign: unknown assign.", "[unknown]", unknownAssign.Value() ); TiXmlText text( "TextNode" ); TiXmlText textCopy( text ); TiXmlText textAssign( "incorrect" ); textAssign = text; XmlTest( "Copy/Assign: text copy.", "TextNode", textCopy.Value() ); XmlTest( "Copy/Assign: text assign.", "TextNode", textAssign.Value() ); TiXmlDeclaration dec; dec.Parse( "<?xml version='1.0' encoding='UTF-8'?>", 0, TIXML_ENCODING_UNKNOWN ); TiXmlDeclaration decCopy( dec ); TiXmlDeclaration decAssign; decAssign = dec; XmlTest( "Copy/Assign: declaration copy.", "UTF-8", decCopy.Encoding() ); XmlTest( "Copy/Assign: text assign.", "UTF-8", decAssign.Encoding() ); TiXmlDocument doc; elementCopy.InsertEndChild( textCopy ); doc.InsertEndChild( decAssign ); doc.InsertEndChild( elementCopy ); doc.InsertEndChild( unknownAssign ); TiXmlDocument docCopy( doc ); TiXmlDocument docAssign; docAssign = docCopy; #ifdef TIXML_USE_STL std::string original, copy, assign; original << doc; copy << docCopy; assign << docAssign; XmlTest( "Copy/Assign: document copy.", original.c_str(), copy.c_str(), true ); XmlTest( "Copy/Assign: document assign.", original.c_str(), assign.c_str(), true ); #endif } ////////////////////////////////////////////////////// #ifdef TIXML_USE_STL printf ("\n** Parsing, no Condense Whitespace **\n"); TiXmlBase::SetCondenseWhiteSpace( false ); { istringstream parse1( "<start>This is \ntext</start>" ); TiXmlElement text1( "text" ); parse1 >> text1; XmlTest ( "Condense white space OFF.", "This is \ntext", text1.FirstChild()->Value(), true ); } TiXmlBase::SetCondenseWhiteSpace( true ); #endif ////////////////////////////////////////////////////// // GetText(); { const char* str = "<foo>This is text</foo>"; TiXmlDocument doc; doc.Parse( str ); const TiXmlElement* element = doc.RootElement(); XmlTest( "GetText() normal use.", "This is text", element->GetText() ); str = "<foo><b>This is text</b></foo>"; doc.Clear(); doc.Parse( str ); element = doc.RootElement(); XmlTest( "GetText() contained element.", element->GetText() == 0, true ); str = "<foo>This is <b>text</b></foo>"; doc.Clear(); TiXmlBase::SetCondenseWhiteSpace( false ); doc.Parse( str ); TiXmlBase::SetCondenseWhiteSpace( true ); element = doc.RootElement(); XmlTest( "GetText() partial.", "This is ", element->GetText() ); } ////////////////////////////////////////////////////// // CDATA { const char* str = "<xmlElement>" "<![CDATA[" "I am > the rules!\n" "...since I make symbolic puns" "]]>" "</xmlElement>"; TiXmlDocument doc; doc.Parse( str ); doc.Print(); XmlTest( "CDATA parse.", doc.FirstChildElement()->FirstChild()->Value(), "I am > the rules!\n...since I make symbolic puns", true ); #ifdef TIXML_USE_STL //cout << doc << '\n'; doc.Clear(); istringstream parse0( str ); parse0 >> doc; //cout << doc << '\n'; XmlTest( "CDATA stream.", doc.FirstChildElement()->FirstChild()->Value(), "I am > the rules!\n...since I make symbolic puns", true ); #endif TiXmlDocument doc1 = doc; //doc.Print(); XmlTest( "CDATA copy.", doc1.FirstChildElement()->FirstChild()->Value(), "I am > the rules!\n...since I make symbolic puns", true ); } { // [ 1482728 ] Wrong wide char parsing char buf[256]; buf[255] = 0; for( int i=0; i<255; ++i ) { buf[i] = (char)((i>=32) ? i : 32); } TIXML_STRING str( "<xmlElement><![CDATA[" ); str += buf; str += "]]></xmlElement>"; TiXmlDocument doc; doc.Parse( str.c_str() ); TiXmlPrinter printer; printer.SetStreamPrinting(); doc.Accept( &printer ); XmlTest( "CDATA with all bytes #1.", str.c_str(), printer.CStr(), true ); #ifdef TIXML_USE_STL doc.Clear(); istringstream iss( printer.Str() ); iss >> doc; std::string out; out << doc; XmlTest( "CDATA with all bytes #2.", out.c_str(), printer.CStr(), true ); #endif } { // [ 1480107 ] Bug-fix for STL-streaming of CDATA that contains tags // CDATA streaming had a couple of bugs, that this tests for. const char* str = "<xmlElement>" "<![CDATA[" "<b>I am > the rules!</b>\n" "...since I make symbolic puns" "]]>" "</xmlElement>"; TiXmlDocument doc; doc.Parse( str ); doc.Print(); XmlTest( "CDATA parse. [ 1480107 ]", doc.FirstChildElement()->FirstChild()->Value(), "<b>I am > the rules!</b>\n...since I make symbolic puns", true ); #ifdef TIXML_USE_STL doc.Clear(); istringstream parse0( str ); parse0 >> doc; XmlTest( "CDATA stream. [ 1480107 ]", doc.FirstChildElement()->FirstChild()->Value(), "<b>I am > the rules!</b>\n...since I make symbolic puns", true ); #endif TiXmlDocument doc1 = doc; //doc.Print(); XmlTest( "CDATA copy. [ 1480107 ]", doc1.FirstChildElement()->FirstChild()->Value(), "<b>I am > the rules!</b>\n...since I make symbolic puns", true ); } ////////////////////////////////////////////////////// // Visit() ////////////////////////////////////////////////////// printf( "\n** Fuzzing... **\n" ); const int FUZZ_ITERATION = 300; // The only goal is not to crash on bad input. int len = (int) strlen( demoStart ); for( int i=0; i<FUZZ_ITERATION; ++i ) { char* demoCopy = new char[ len+1 ]; strcpy( demoCopy, demoStart ); demoCopy[ i%len ] = (char)((i+1)*3); demoCopy[ (i*7)%len ] = '>'; demoCopy[ (i*11)%len ] = '<'; TiXmlDocument xml; xml.Parse( demoCopy ); delete [] demoCopy; } printf( "** Fuzzing Complete. **\n" ); ////////////////////////////////////////////////////// printf ("\n** Bug regression tests **\n"); // InsertBeforeChild and InsertAfterChild causes crash. { TiXmlElement parent( "Parent" ); TiXmlElement childText0( "childText0" ); TiXmlElement childText1( "childText1" ); TiXmlNode* childNode0 = parent.InsertEndChild( childText0 ); TiXmlNode* childNode1 = parent.InsertBeforeChild( childNode0, childText1 ); XmlTest( "Test InsertBeforeChild on empty node.", ( childNode1 == parent.FirstChild() ), true ); } { // InsertBeforeChild and InsertAfterChild causes crash. TiXmlElement parent( "Parent" ); TiXmlElement childText0( "childText0" ); TiXmlElement childText1( "childText1" ); TiXmlNode* childNode0 = parent.InsertEndChild( childText0 ); TiXmlNode* childNode1 = parent.InsertAfterChild( childNode0, childText1 ); XmlTest( "Test InsertAfterChild on empty node. ", ( childNode1 == parent.LastChild() ), true ); } // Reports of missing constructors, irregular string problems. { // Missing constructor implementation. No test -- just compiles. TiXmlText text( "Missing" ); #ifdef TIXML_USE_STL // Missing implementation: TiXmlDocument doc; string name = "missing"; doc.LoadFile( name ); TiXmlText textSTL( name ); #else // verifying some basic string functions: TiXmlString a; TiXmlString b( "Hello" ); TiXmlString c( "ooga" ); c = " World!"; a = b; a += c; a = a; XmlTest( "Basic TiXmlString test. ", "Hello World!", a.c_str() ); #endif } // Long filenames crashing STL version { TiXmlDocument doc( "midsummerNightsDreamWithAVeryLongFilenameToConfuseTheStringHandlingRoutines.xml" ); bool loadOkay = doc.LoadFile(); loadOkay = true; // get rid of compiler warning. // Won't pass on non-dev systems. Just a "no crash" check. //XmlTest( "Long filename. ", true, loadOkay ); } { // Entities not being written correctly. // From Lynn Allen const char* passages = "<?xml version=\"1.0\" standalone=\"no\" ?>" "<passages count=\"006\" formatversion=\"20020620\">" "<psg context=\"Line 5 has "quotation marks" and 'apostrophe marks'." " It also has <, >, and &, as well as a fake copyright ©.\"> </psg>" "</passages>"; TiXmlDocument doc( "passages.xml" ); doc.Parse( passages ); TiXmlElement* psg = doc.RootElement()->FirstChildElement(); const char* context = psg->Attribute( "context" ); const char* expected = "Line 5 has \"quotation marks\" and 'apostrophe marks'. It also has <, >, and &, as well as a fake copyright \xC2\xA9."; XmlTest( "Entity transformation: read. ", expected, context, true ); FILE* textfile = fopen( "textfile.txt", "w" ); if ( textfile ) { psg->Print( textfile, 0 ); fclose( textfile ); } textfile = fopen( "textfile.txt", "r" ); assert( textfile ); if ( textfile ) { char buf[ 1024 ]; fgets( buf, 1024, textfile ); XmlTest( "Entity transformation: write. ", "<psg context=\'Line 5 has "quotation marks" and 'apostrophe marks'." " It also has <, >, and &, as well as a fake copyright \xC2\xA9.' />", buf, true ); } fclose( textfile ); } { FILE* textfile = fopen( "test5.xml", "w" ); if ( textfile ) { fputs("<?xml version='1.0'?><a.elem xmi.version='2.0'/>", textfile); fclose(textfile); TiXmlDocument doc; doc.LoadFile( "test5.xml" ); XmlTest( "dot in element attributes and names", doc.Error(), 0); } } { FILE* textfile = fopen( "test6.xml", "w" ); if ( textfile ) { fputs("<element><Name>1.1 Start easy ignore fin thickness
</Name></element>", textfile ); fclose(textfile); TiXmlDocument doc; bool result = doc.LoadFile( "test6.xml" ); XmlTest( "Entity with one digit.", result, true ); TiXmlText* text = doc.FirstChildElement()->FirstChildElement()->FirstChild()->ToText(); XmlTest( "Entity with one digit.", text->Value(), "1.1 Start easy ignore fin thickness\n" ); } } { // DOCTYPE not preserved (950171) // const char* doctype = "<?xml version=\"1.0\" ?>" "<!DOCTYPE PLAY SYSTEM 'play.dtd'>" "<!ELEMENT title (#PCDATA)>" "<!ELEMENT books (title,authors)>" "<element />"; TiXmlDocument doc; doc.Parse( doctype ); doc.SaveFile( "test7.xml" ); doc.Clear(); doc.LoadFile( "test7.xml" ); TiXmlHandle docH( &doc ); TiXmlUnknown* unknown = docH.Child( 1 ).Unknown(); XmlTest( "Correct value of unknown.", "!DOCTYPE PLAY SYSTEM 'play.dtd'", unknown->Value() ); #ifdef TIXML_USE_STL TiXmlNode* node = docH.Child( 2 ).Node(); std::string str; str << (*node); XmlTest( "Correct streaming of unknown.", "<!ELEMENT title (#PCDATA)>", str.c_str() ); #endif } { // [ 791411 ] Formatting bug // Comments do not stream out correctly. const char* doctype = "<!-- Somewhat<evil> -->"; TiXmlDocument doc; doc.Parse( doctype ); TiXmlHandle docH( &doc ); TiXmlComment* comment = docH.Child( 0 ).Node()->ToComment(); XmlTest( "Comment formatting.", " Somewhat<evil> ", comment->Value() ); #ifdef TIXML_USE_STL std::string str; str << (*comment); XmlTest( "Comment streaming.", "<!-- Somewhat<evil> -->", str.c_str() ); #endif } { // [ 870502 ] White space issues TiXmlDocument doc; TiXmlText* text; TiXmlHandle docH( &doc ); const char* doctype0 = "<element> This has leading and trailing space </element>"; const char* doctype1 = "<element>This has internal space</element>"; const char* doctype2 = "<element> This has leading, trailing, and internal space </element>"; TiXmlBase::SetCondenseWhiteSpace( false ); doc.Clear(); doc.Parse( doctype0 ); text = docH.FirstChildElement( "element" ).Child( 0 ).Text(); XmlTest( "White space kept.", " This has leading and trailing space ", text->Value() ); doc.Clear(); doc.Parse( doctype1 ); text = docH.FirstChildElement( "element" ).Child( 0 ).Text(); XmlTest( "White space kept.", "This has internal space", text->Value() ); doc.Clear(); doc.Parse( doctype2 ); text = docH.FirstChildElement( "element" ).Child( 0 ).Text(); XmlTest( "White space kept.", " This has leading, trailing, and internal space ", text->Value() ); TiXmlBase::SetCondenseWhiteSpace( true ); doc.Clear(); doc.Parse( doctype0 ); text = docH.FirstChildElement( "element" ).Child( 0 ).Text(); XmlTest( "White space condensed.", "This has leading and trailing space", text->Value() ); doc.Clear(); doc.Parse( doctype1 ); text = docH.FirstChildElement( "element" ).Child( 0 ).Text(); XmlTest( "White space condensed.", "This has internal space", text->Value() ); doc.Clear(); doc.Parse( doctype2 ); text = docH.FirstChildElement( "element" ).Child( 0 ).Text(); XmlTest( "White space condensed.", "This has leading, trailing, and internal space", text->Value() ); } { // Double attributes const char* doctype = "<element attr='red' attr='blue' />"; TiXmlDocument doc; doc.Parse( doctype ); XmlTest( "Parsing repeated attributes.", 0, (int)doc.Error() ); // not an error to tinyxml XmlTest( "Parsing repeated attributes.", "blue", doc.FirstChildElement( "element" )->Attribute( "attr" ) ); } { // Embedded null in stream. const char* doctype = "<element att\0r='red' attr='blue' />"; TiXmlDocument doc; doc.Parse( doctype ); XmlTest( "Embedded null throws error.", true, doc.Error() ); #ifdef TIXML_USE_STL istringstream strm( doctype ); doc.Clear(); doc.ClearError(); strm >> doc; XmlTest( "Embedded null throws error.", true, doc.Error() ); #endif } { // Legacy mode test. (This test may only pass on a western system) const char* str = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" "<?>" "C?nt?nt???????" "</?>"; TiXmlDocument doc; doc.Parse( str ); TiXmlHandle docHandle( &doc ); TiXmlHandle aHandle = docHandle.FirstChildElement( "?" ); TiXmlHandle tHandle = aHandle.Child( 0 ); assert( aHandle.Element() ); assert( tHandle.Text() ); XmlTest( "ISO-8859-1 Parsing.", "C?nt?nt???????", tHandle.Text()->Value() ); } { // Empty documents should return TIXML_ERROR_PARSING_EMPTY, bug 1070717 const char* str = " "; TiXmlDocument doc; doc.Parse( str ); XmlTest( "Empty document error TIXML_ERROR_DOCUMENT_EMPTY", TiXmlBase::TIXML_ERROR_DOCUMENT_EMPTY, doc.ErrorId() ); } #ifndef TIXML_USE_STL { // String equality. [ 1006409 ] string operator==/!= no worky in all cases TiXmlString temp; XmlTest( "Empty tinyxml string compare equal", ( temp == "" ), true ); TiXmlString foo; TiXmlString bar( "" ); XmlTest( "Empty tinyxml string compare equal", ( foo == bar ), true ); } #endif { // Bug [ 1195696 ] from marlonism TiXmlBase::SetCondenseWhiteSpace(false); TiXmlDocument xml; xml.Parse("<text><break/>This hangs</text>"); XmlTest( "Test safe error return.", xml.Error(), false ); } { // Bug [ 1243992 ] - another infinite loop TiXmlDocument doc; doc.SetCondenseWhiteSpace(false); doc.Parse("<p><pb></pb>test</p>"); } { // Low entities TiXmlDocument xml; xml.Parse( "<test></test>" ); const char result[] = { 0x0e, 0 }; XmlTest( "Low entities.", xml.FirstChildElement()->GetText(), result ); xml.Print(); } { // Bug [ 1451649 ] Attribute values with trailing quotes not handled correctly TiXmlDocument xml; xml.Parse( "<foo attribute=bar\" />" ); XmlTest( "Throw error with bad end quotes.", xml.Error(), true ); } #ifdef TIXML_USE_STL { // Bug [ 1449463 ] Consider generic query TiXmlDocument xml; xml.Parse( "<foo bar='3' barStr='a string'/>" ); TiXmlElement* ele = xml.FirstChildElement(); double d; int i; float f; bool b; //std::string str; XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &d ), TIXML_SUCCESS ); XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &i ), TIXML_SUCCESS ); XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &f ), TIXML_SUCCESS ); XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "bar", &b ), TIXML_WRONG_TYPE ); XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "nobar", &b ), TIXML_NO_ATTRIBUTE ); //XmlTest( "QueryValueAttribute", ele->QueryValueAttribute( "barStr", &str ), TIXML_SUCCESS ); XmlTest( "QueryValueAttribute", (d==3.0), true ); XmlTest( "QueryValueAttribute", (i==3), true ); XmlTest( "QueryValueAttribute", (f==3.0f), true ); //XmlTest( "QueryValueAttribute", (str==std::string( "a string" )), true ); } #endif #ifdef TIXML_USE_STL { // [ 1505267 ] redundant malloc in TiXmlElement::Attribute TiXmlDocument xml; xml.Parse( "<foo bar='3' />" ); TiXmlElement* ele = xml.FirstChildElement(); double d; int i; std::string bar = "bar"; const std::string* atrrib = ele->Attribute( bar ); ele->Attribute( bar, &d ); ele->Attribute( bar, &i ); XmlTest( "Attribute", atrrib->empty(), false ); XmlTest( "Attribute", (d==3.0), true ); XmlTest( "Attribute", (i==3), true ); } #endif { // [ 1356059 ] Allow TiXMLDocument to only be at the top level TiXmlDocument xml, xml2; xml.InsertEndChild( xml2 ); XmlTest( "Document only at top level.", xml.Error(), true ); XmlTest( "Document only at top level.", xml.ErrorId(), TiXmlBase::TIXML_ERROR_DOCUMENT_TOP_ONLY ); } { // [ 1663758 ] Failure to report error on bad XML TiXmlDocument xml; xml.Parse("<x>"); XmlTest("Missing end tag at end of input", xml.Error(), true); xml.Parse("<x> "); XmlTest("Missing end tag with trailing whitespace", xml.Error(), true); } { // [ 1635701 ] fail to parse files with a tag separated into two lines // I'm not sure this is a bug. Marked 'pending' for feedback. TiXmlDocument xml; xml.Parse( "<title><p>text</p\n><title>" ); //xml.Print(); //XmlTest( "Tag split by newline", xml.Error(), false ); } #ifdef TIXML_USE_STL { // [ 1475201 ] TinyXML parses entities in comments TiXmlDocument xml; istringstream parse1( "<!-- declarations for <head> & <body> -->" "<!-- far & away -->" ); parse1 >> xml; TiXmlNode* e0 = xml.FirstChild(); TiXmlNode* e1 = e0->NextSibling(); TiXmlComment* c0 = e0->ToComment(); TiXmlComment* c1 = e1->ToComment(); XmlTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true ); XmlTest( "Comments ignore entities.", " far & away ", c1->Value(), true ); } #endif { // [ 1475201 ] TinyXML parses entities in comments TiXmlDocument xml; xml.Parse("<!-- declarations for <head> & <body> -->" "<!-- far & away -->" ); TiXmlNode* e0 = xml.FirstChild(); TiXmlNode* e1 = e0->NextSibling(); TiXmlComment* c0 = e0->ToComment(); TiXmlComment* c1 = e1->ToComment(); XmlTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true ); XmlTest( "Comments ignore entities.", " far & away ", c1->Value(), true ); } /* { TiXmlDocument xml; xml.Parse( "<tag>/</tag>" ); xml.Print(); xml.FirstChild()->Print( stdout, 0 ); xml.FirstChild()->Type(); } */ /* 1417717 experiment { TiXmlDocument xml; xml.Parse("<text>Dan & Tracie</text>"); xml.Print(stdout); } { TiXmlDocument xml; xml.Parse("<text>Dan &foo; Tracie</text>"); xml.Print(stdout); } */ #if defined( WIN32 ) && defined( TUNE ) _CrtMemCheckpoint( &endMemState ); //_CrtMemDumpStatistics( &endMemState ); _CrtMemState diffMemState; _CrtMemDifference( &diffMemState, &startMemState, &endMemState ); _CrtMemDumpStatistics( &diffMemState ); #endif printf ("\nPass %d, Fail %d\n", gPass, gFail); return gFail; }
// \brief Load the config file (sounds.xml) for nav sounds // Can be located in a folder "sounds" in the skin or from a // subfolder of the folder "sounds" in the root directory of // xbmc bool CGUIAudioManager::Load() { CSingleLock lock(m_cs); UnLoad(); if (CSettings::Get().GetString("lookandfeel.soundskin")=="OFF") return true; else Enable(true); std::string soundSkin = CSettings::Get().GetString("lookandfeel.soundskin"); if (soundSkin == "SKINDEFAULT") { m_strMediaDir = URIUtils::AddFileToFolder(g_SkinInfo->Path(), "sounds"); } else { //check if sound skin is located in home, otherwise fallback to built-ins m_strMediaDir = URIUtils::AddFileToFolder("special://home/sounds", soundSkin); if (!XFILE::CDirectory::Exists(m_strMediaDir)) m_strMediaDir = URIUtils::AddFileToFolder("special://xbmc/sounds", soundSkin); } std::string strSoundsXml = URIUtils::AddFileToFolder(m_strMediaDir, "sounds.xml"); // Load our xml file CXBMCTinyXML xmlDoc; CLog::Log(LOGINFO, "Loading %s", strSoundsXml.c_str()); // Load the config file if (!xmlDoc.LoadFile(strSoundsXml)) { CLog::Log(LOGNOTICE, "%s, Line %d\n%s", strSoundsXml.c_str(), xmlDoc.ErrorRow(), xmlDoc.ErrorDesc()); return false; } TiXmlElement* pRoot = xmlDoc.RootElement(); std::string strValue = pRoot->Value(); if ( strValue != "sounds") { CLog::Log(LOGNOTICE, "%s Doesn't contain <sounds>", strSoundsXml.c_str()); return false; } // Load sounds for actions TiXmlElement* pActions = pRoot->FirstChildElement("actions"); if (pActions) { TiXmlNode* pAction = pActions->FirstChild("action"); while (pAction) { TiXmlNode* pIdNode = pAction->FirstChild("name"); int id = 0; // action identity if (pIdNode && pIdNode->FirstChild()) { CButtonTranslator::TranslateActionString(pIdNode->FirstChild()->Value(), id); } TiXmlNode* pFileNode = pAction->FirstChild("file"); std::string strFile; if (pFileNode && pFileNode->FirstChild()) strFile += pFileNode->FirstChild()->Value(); if (id > 0 && !strFile.empty()) { std::string filename = URIUtils::AddFileToFolder(m_strMediaDir, strFile); IAESound *sound = LoadSound(filename); if (sound) m_actionSoundMap.insert(pair<int, IAESound *>(id, sound)); } pAction = pAction->NextSibling(); } } // Load window specific sounds TiXmlElement* pWindows = pRoot->FirstChildElement("windows"); if (pWindows) { TiXmlNode* pWindow = pWindows->FirstChild("window"); while (pWindow) { int id = 0; TiXmlNode* pIdNode = pWindow->FirstChild("name"); if (pIdNode) { if (pIdNode->FirstChild()) id = CButtonTranslator::TranslateWindow(pIdNode->FirstChild()->Value()); } CWindowSounds sounds; sounds.initSound = LoadWindowSound(pWindow, "activate" ); sounds.deInitSound = LoadWindowSound(pWindow, "deactivate"); if (id > 0) m_windowSoundMap.insert(pair<int, CWindowSounds>(id, sounds)); pWindow = pWindow->NextSibling(); } } return true; }
CGUIControl* CGUIControlFactory::Create(int parentID, const CRect &rect, TiXmlElement* pControlNode, bool insideContainer) { // get the control type CStdString strType = GetType(pControlNode); CGUIControl::GUICONTROLTYPES type = TranslateControlType(strType); int id = 0; float posX = 0, posY = 0; float width = 0, height = 0; float minWidth = 0; int left = 0, right = 0, up = 0, down = 0, next = 0, prev = 0; vector<CGUIActionDescriptor> leftActions, rightActions, upActions, downActions, nextActions, prevActions; int pageControl = 0; CGUIInfoColor colorDiffuse(0xFFFFFFFF); int defaultControl = 0; bool defaultAlways = false; CStdString strTmp; int singleInfo = 0; CStdString strLabel; int iUrlSet=0; int iToggleSelect; float spinWidth = 16; float spinHeight = 16; float spinPosX = 0, spinPosY = 0; float checkWidth = 0, checkHeight = 0; CStdString strSubType; int iType = SPIN_CONTROL_TYPE_TEXT; int iMin = 0; int iMax = 100; int iInterval = 1; float fMin = 0.0f; float fMax = 1.0f; float fInterval = 0.1f; bool bReverse = true; bool bReveal = false; CTextureInfo textureBackground, textureLeft, textureRight, textureMid, textureOverlay; CTextureInfo textureNib, textureNibFocus, textureBar, textureBarFocus; CTextureInfo textureLeftFocus, textureRightFocus; CTextureInfo textureUp, textureDown; CTextureInfo textureUpFocus, textureDownFocus; CTextureInfo texture, borderTexture; CGUIInfoLabel textureFile; CTextureInfo textureCheckMark, textureCheckMarkNF; CTextureInfo textureFocus, textureNoFocus; CTextureInfo textureAltFocus, textureAltNoFocus; CTextureInfo textureRadioOn, textureRadioOff; CTextureInfo imageNoFocus, imageFocus; CGUIInfoLabel texturePath; CRect borderSize; float sliderWidth = 150, sliderHeight = 16; CPoint offset; bool bHasPath = false; vector<CGUIActionDescriptor> clickActions; vector<CGUIActionDescriptor> altclickActions; vector<CGUIActionDescriptor> focusActions; vector<CGUIActionDescriptor> unfocusActions; vector<CGUIActionDescriptor> textChangeActions; CStdString strTitle = ""; CStdString strRSSTags = ""; int iNumSlots = 7; float buttonGap = 5; int iDefaultSlot = 2; int iMovementRange = 0; bool bHorizontal = false; int iAlpha = 0; bool bWrapAround = true; bool bSmoothScrolling = true; CAspectRatio aspect; #ifdef PRE_SKIN_VERSION_9_10_COMPATIBILITY if (insideContainer) // default for inside containers is keep aspect.ratio = CAspectRatio::AR_KEEP; #endif int iVisibleCondition = 0; CGUIInfoBool allowHiddenFocus(false); int enableCondition = 0; vector<CAnimation> animations; bool bScrollLabel = false; bool bPulse = true; unsigned int timePerImage = 0; unsigned int fadeTime = 0; unsigned int timeToPauseAtEnd = 0; bool randomized = false; bool loop = true; bool wrapMultiLine = false; ORIENTATION orientation = VERTICAL; bool showOnePage = true; bool scrollOut = true; int preloadItems = 0; CLabelInfo labelInfo; CLabelInfo spinInfo; CGUIInfoColor textColor3; CGUIInfoColor headlineColor; float radioWidth = 0; float radioHeight = 0; float radioPosX = 0; float radioPosY = 0; CStdString altLabel; CStdString strLabel2; CStdString action; int focusPosition = 0; int scrollTime = 200; int timeBlocks = 36; int rulerUnit = 12; bool useControlCoords = false; bool renderFocusedLast = false; CRect hitRect; CPoint camera; bool hasCamera = false; bool resetOnLabelChange = true; bool bPassword = false; ///////////////////////////////////////////////////////////////////////////// // Read control properties from XML // if (!pControlNode->Attribute("id", (int*) &id)) XMLUtils::GetInt(pControlNode, "id", (int&) id); // backward compatibility - not desired // TODO: Perhaps we should check here whether id is valid for focusable controls // such as buttons etc. For labels/fadelabels/images it does not matter XMLUtils::GetFloat(pControlNode, "posx", posX); XMLUtils::GetFloat(pControlNode, "posy", posY); // Convert these from relative coords CStdString pos; XMLUtils::GetString(pControlNode, "posx", pos); if (pos.Right(1) == "r") posX = rect.Width() - posX; XMLUtils::GetString(pControlNode, "posy", pos); if (pos.Right(1) == "r") posY = rect.Height() - posY; GetDimension(pControlNode, "width", width, minWidth); XMLUtils::GetFloat(pControlNode, "height", height); XMLUtils::GetFloat(pControlNode, "offsetx", offset.x); XMLUtils::GetFloat(pControlNode, "offsety", offset.y); // adjust width and height accordingly for groups. Groups should // take the width/height of the parent (adjusted for positioning) // if none is defined. if (type == CGUIControl::GUICONTROL_GROUP || type == CGUIControl::GUICONTROL_GROUPLIST) { if (!width) width = max(rect.x2 - posX, 0.0f); if (!height) height = max(rect.y2 - posY, 0.0f); } hitRect.SetRect(posX, posY, posX + width, posY + height); GetHitRect(pControlNode, hitRect); if (!GetNavigation(pControlNode, "onup", up, upActions)) up = id - 1; if (!GetNavigation(pControlNode, "ondown", down, downActions)) down = id + 1; if (!GetNavigation(pControlNode, "onleft", left, leftActions)) left = id; if (!GetNavigation(pControlNode, "onright", right, rightActions)) right = id; if (!GetNavigation(pControlNode, "onnext", next, nextActions)) next = id; if (!GetNavigation(pControlNode, "onprev", prev, prevActions)) prev = id; if (XMLUtils::GetInt(pControlNode, "defaultcontrol", defaultControl)) { const char *always = pControlNode->FirstChildElement("defaultcontrol")->Attribute("always"); if (always && strnicmp(always, "true", 4) == 0) defaultAlways = true; } XMLUtils::GetInt(pControlNode, "pagecontrol", pageControl); GetInfoColor(pControlNode, "colordiffuse", colorDiffuse); GetConditionalVisibility(pControlNode, iVisibleCondition, allowHiddenFocus); GetCondition(pControlNode, "enable", enableCondition); CRect animRect(posX, posY, posX + width, posY + height); GetAnimations(pControlNode, animRect, animations); GetInfoColor(pControlNode, "textcolor", labelInfo.textColor); GetInfoColor(pControlNode, "focusedcolor", labelInfo.focusedColor); GetInfoColor(pControlNode, "disabledcolor", labelInfo.disabledColor); GetInfoColor(pControlNode, "shadowcolor", labelInfo.shadowColor); GetInfoColor(pControlNode, "selectedcolor", labelInfo.selectedColor); XMLUtils::GetFloat(pControlNode, "textoffsetx", labelInfo.offsetX); XMLUtils::GetFloat(pControlNode, "textoffsety", labelInfo.offsetY); int angle = 0; // use the negative angle to compensate for our vertically flipped cartesian plane if (XMLUtils::GetInt(pControlNode, "angle", angle)) labelInfo.angle = (float)-angle; CStdString strFont; if (XMLUtils::GetString(pControlNode, "font", strFont)) labelInfo.font = g_fontManager.GetFont(strFont); GetAlignment(pControlNode, "align", labelInfo.align); uint32_t alignY = 0; if (GetAlignmentY(pControlNode, "aligny", alignY)) labelInfo.align |= alignY; if (XMLUtils::GetFloat(pControlNode, "textwidth", labelInfo.width)) labelInfo.align |= XBFONT_TRUNCATED; GetMultipleString(pControlNode, "onclick", clickActions); GetMultipleString(pControlNode, "ontextchange", textChangeActions); GetMultipleString(pControlNode, "onfocus", focusActions); GetMultipleString(pControlNode, "onunfocus", unfocusActions); GetMultipleString(pControlNode, "altclick", altclickActions); CStdString infoString; if (XMLUtils::GetString(pControlNode, "info", infoString)) singleInfo = g_infoManager.TranslateString(infoString); GetTexture(pControlNode, "texturefocus", textureFocus); GetTexture(pControlNode, "texturenofocus", textureNoFocus); GetTexture(pControlNode, "alttexturefocus", textureAltFocus); GetTexture(pControlNode, "alttexturenofocus", textureAltNoFocus); CStdString strToggleSelect; XMLUtils::GetString(pControlNode, "usealttexture", strToggleSelect); XMLUtils::GetString(pControlNode, "selected", strToggleSelect); iToggleSelect = g_infoManager.TranslateString(strToggleSelect); XMLUtils::GetBoolean(pControlNode, "haspath", bHasPath); GetTexture(pControlNode, "textureup", textureUp); GetTexture(pControlNode, "texturedown", textureDown); GetTexture(pControlNode, "textureupfocus", textureUpFocus); GetTexture(pControlNode, "texturedownfocus", textureDownFocus); GetTexture(pControlNode, "textureleft", textureLeft); GetTexture(pControlNode, "textureright", textureRight); GetTexture(pControlNode, "textureleftfocus", textureLeftFocus); GetTexture(pControlNode, "texturerightfocus", textureRightFocus); GetInfoColor(pControlNode, "spincolor", spinInfo.textColor); if (XMLUtils::GetString(pControlNode, "spinfont", strFont)) spinInfo.font = g_fontManager.GetFont(strFont); if (!spinInfo.font) spinInfo.font = labelInfo.font; XMLUtils::GetFloat(pControlNode, "spinwidth", spinWidth); XMLUtils::GetFloat(pControlNode, "spinheight", spinHeight); XMLUtils::GetFloat(pControlNode, "spinposx", spinPosX); XMLUtils::GetFloat(pControlNode, "spinposy", spinPosY); XMLUtils::GetFloat(pControlNode, "markwidth", checkWidth); XMLUtils::GetFloat(pControlNode, "markheight", checkHeight); XMLUtils::GetFloat(pControlNode, "sliderwidth", sliderWidth); XMLUtils::GetFloat(pControlNode, "sliderheight", sliderHeight); GetTexture(pControlNode, "texturecheckmark", textureCheckMark); GetTexture(pControlNode, "texturecheckmarknofocus", textureCheckMarkNF); GetTexture(pControlNode, "textureradiofocus", textureRadioOn); // backward compatibility GetTexture(pControlNode, "textureradionofocus", textureRadioOff); GetTexture(pControlNode, "textureradioon", textureRadioOn); GetTexture(pControlNode, "textureradiooff", textureRadioOff); GetTexture(pControlNode, "texturesliderbackground", textureBackground); GetTexture(pControlNode, "texturesliderbar", textureBar); GetTexture(pControlNode, "texturesliderbarfocus", textureBarFocus); GetTexture(pControlNode, "textureslidernib", textureNib); GetTexture(pControlNode, "textureslidernibfocus", textureNibFocus); XMLUtils::GetString(pControlNode, "title", strTitle); XMLUtils::GetString(pControlNode, "tagset", strRSSTags); GetInfoColor(pControlNode, "headlinecolor", headlineColor); GetInfoColor(pControlNode, "titlecolor", textColor3); if (XMLUtils::GetString(pControlNode, "subtype", strSubType)) { strSubType.ToLower(); if ( strSubType == "int") iType = SPIN_CONTROL_TYPE_INT; else if ( strSubType == "page") iType = SPIN_CONTROL_TYPE_PAGE; else if ( strSubType == "float") iType = SPIN_CONTROL_TYPE_FLOAT; else iType = SPIN_CONTROL_TYPE_TEXT; } if (!GetIntRange(pControlNode, "range", iMin, iMax, iInterval)) { GetFloatRange(pControlNode, "range", fMin, fMax, fInterval); } XMLUtils::GetBoolean(pControlNode, "reverse", bReverse); XMLUtils::GetBoolean(pControlNode, "reveal", bReveal); GetTexture(pControlNode, "texturebg", textureBackground); GetTexture(pControlNode, "lefttexture", textureLeft); GetTexture(pControlNode, "midtexture", textureMid); GetTexture(pControlNode, "righttexture", textureRight); GetTexture(pControlNode, "overlaytexture", textureOverlay); // the <texture> tag can be overridden by the <info> tag GetInfoTexture(pControlNode, "texture", texture, textureFile); GetTexture(pControlNode, "bordertexture", borderTexture); GetTexture(pControlNode, "imagefolder", imageNoFocus); GetTexture(pControlNode, "imagefolderfocus", imageFocus); // fade label can have a whole bunch, but most just have one vector<CGUIInfoLabel> infoLabels; GetInfoLabels(pControlNode, "label", infoLabels); GetString(pControlNode, "label", strLabel); GetString(pControlNode, "altlabel", altLabel); GetString(pControlNode, "label2", strLabel2); XMLUtils::GetBoolean(pControlNode, "wrapmultiline", wrapMultiLine); XMLUtils::GetInt(pControlNode,"urlset",iUrlSet); // stuff for button scroller if ( XMLUtils::GetString(pControlNode, "orientation", strTmp) ) { if (strTmp.ToLower() == "horizontal") { bHorizontal = true; orientation = HORIZONTAL; } } XMLUtils::GetFloat(pControlNode, "buttongap", buttonGap); XMLUtils::GetFloat(pControlNode, "itemgap", buttonGap); XMLUtils::GetInt(pControlNode, "numbuttons", iNumSlots); XMLUtils::GetInt(pControlNode, "movement", iMovementRange); XMLUtils::GetInt(pControlNode, "defaultbutton", iDefaultSlot); XMLUtils::GetInt(pControlNode, "alpha", iAlpha); XMLUtils::GetBoolean(pControlNode, "wraparound", bWrapAround); XMLUtils::GetBoolean(pControlNode, "smoothscrolling", bSmoothScrolling); GetAspectRatio(pControlNode, "aspectratio", aspect); XMLUtils::GetBoolean(pControlNode, "scroll", bScrollLabel); XMLUtils::GetBoolean(pControlNode,"pulseonselect", bPulse); XMLUtils::GetInt(pControlNode, "timeblocks", timeBlocks); XMLUtils::GetInt(pControlNode, "rulerunit", rulerUnit); GetInfoTexture(pControlNode, "imagepath", texture, texturePath); XMLUtils::GetUInt(pControlNode,"timeperimage", timePerImage); XMLUtils::GetUInt(pControlNode,"fadetime", fadeTime); XMLUtils::GetUInt(pControlNode,"pauseatend", timeToPauseAtEnd); XMLUtils::GetBoolean(pControlNode, "randomize", randomized); XMLUtils::GetBoolean(pControlNode, "loop", loop); XMLUtils::GetBoolean(pControlNode, "scrollout", scrollOut); XMLUtils::GetFloat(pControlNode, "radiowidth", radioWidth); XMLUtils::GetFloat(pControlNode, "radioheight", radioHeight); XMLUtils::GetFloat(pControlNode, "radioposx", radioPosX); XMLUtils::GetFloat(pControlNode, "radioposy", radioPosY); CStdString borderStr; if (XMLUtils::GetString(pControlNode, "bordersize", borderStr)) GetRectFromString(borderStr, borderSize); XMLUtils::GetBoolean(pControlNode, "showonepage", showOnePage); XMLUtils::GetInt(pControlNode, "focusposition", focusPosition); XMLUtils::GetInt(pControlNode, "scrolltime", scrollTime); XMLUtils::GetInt(pControlNode, "preloaditems", preloadItems, 0, 2); XMLUtils::GetBoolean(pControlNode, "usecontrolcoords", useControlCoords); XMLUtils::GetBoolean(pControlNode, "renderfocusedlast", renderFocusedLast); XMLUtils::GetBoolean(pControlNode, "resetonlabelchange", resetOnLabelChange); XMLUtils::GetBoolean(pControlNode, "password", bPassword); // view type VIEW_TYPE viewType = VIEW_TYPE_NONE; CStdString viewLabel; if (type == CGUIControl::GUICONTAINER_PANEL) { viewType = VIEW_TYPE_ICON; viewLabel = g_localizeStrings.Get(536); } else if (type == CGUIControl::GUICONTAINER_LIST) { viewType = VIEW_TYPE_LIST; viewLabel = g_localizeStrings.Get(535); } else { viewType = VIEW_TYPE_WRAP; viewLabel = g_localizeStrings.Get(541); } TiXmlElement *itemElement = pControlNode->FirstChildElement("viewtype"); if (itemElement && itemElement->FirstChild()) { CStdString type = itemElement->FirstChild()->Value(); if (type == "list") viewType = VIEW_TYPE_LIST; else if (type == "icon") viewType = VIEW_TYPE_ICON; else if (type == "biglist") viewType = VIEW_TYPE_BIG_LIST; else if (type == "bigicon") viewType = VIEW_TYPE_BIG_ICON; else if (type == "wide") viewType = VIEW_TYPE_WIDE; else if (type == "bigwide") viewType = VIEW_TYPE_BIG_WIDE; else if (type == "wrap") viewType = VIEW_TYPE_WRAP; else if (type == "bigwrap") viewType = VIEW_TYPE_BIG_WRAP; const char *label = itemElement->Attribute("label"); if (label) viewLabel = CGUIInfoLabel::GetLabel(FilterLabel(label)); } TiXmlElement *cam = pControlNode->FirstChildElement("camera"); if (cam) { hasCamera = true; cam->QueryFloatAttribute("x", &camera.x); cam->QueryFloatAttribute("y", &camera.y); } XMLUtils::GetInt(pControlNode, "scrollspeed", labelInfo.scrollSpeed); spinInfo.scrollSpeed = labelInfo.scrollSpeed; GetString(pControlNode, "scrollsuffix", labelInfo.scrollSuffix); spinInfo.scrollSuffix = labelInfo.scrollSuffix; XMLUtils::GetString(pControlNode, "action", action); ///////////////////////////////////////////////////////////////////////////// // Instantiate a new control using the properties gathered above // CGUIControl *control = NULL; if (type == CGUIControl::GUICONTROL_GROUP) { if (insideContainer) { control = new CGUIListGroup(parentID, id, posX, posY, width, height); } else { control = new CGUIControlGroup( parentID, id, posX, posY, width, height); ((CGUIControlGroup *)control)->SetDefaultControl(defaultControl, defaultAlways); ((CGUIControlGroup *)control)->SetRenderFocusedLast(renderFocusedLast); } } else if (type == CGUIControl::GUICONTROL_GROUPLIST) { control = new CGUIControlGroupList( parentID, id, posX, posY, width, height, buttonGap, pageControl, orientation, useControlCoords, labelInfo.align, scrollTime); ((CGUIControlGroup *)control)->SetRenderFocusedLast(renderFocusedLast); } else if (type == CGUIControl::GUICONTROL_LABEL) { const CGUIInfoLabel &content = (infoLabels.size()) ? infoLabels[0] : CGUIInfoLabel(""); if (insideContainer) { // inside lists we use CGUIListLabel control = new CGUIListLabel(parentID, id, posX, posY, width, height, labelInfo, content, bScrollLabel); } else { control = new CGUILabelControl( parentID, id, posX, posY, width, height, labelInfo, wrapMultiLine, bHasPath); ((CGUILabelControl *)control)->SetInfo(content); ((CGUILabelControl *)control)->SetWidthControl(minWidth, bScrollLabel); } } else if (type == CGUIControl::GUICONTROL_EDIT) { control = new CGUIEditControl( parentID, id, posX, posY, width, height, textureFocus, textureNoFocus, labelInfo, strLabel); if (bPassword) ((CGUIEditControl *) control)->SetInputType(CGUIEditControl::INPUT_TYPE_PASSWORD, 0); ((CGUIEditControl *) control)->SetTextChangeActions(textChangeActions); } else if (type == CGUIControl::GUICONTROL_VIDEO) { control = new CGUIVideoControl( parentID, id, posX, posY, width, height); } else if (type == CGUIControl::GUICONTROL_FADELABEL) { control = new CGUIFadeLabelControl( parentID, id, posX, posY, width, height, labelInfo, scrollOut, timeToPauseAtEnd, resetOnLabelChange); ((CGUIFadeLabelControl *)control)->SetInfo(infoLabels); } else if (type == CGUIControl::GUICONTROL_RSS) { control = new CGUIRSSControl( parentID, id, posX, posY, width, height, labelInfo, textColor3, headlineColor, strRSSTags); std::map<int,CSettings::RssSet>::iterator iter=g_settings.m_mapRssUrls.find(iUrlSet); if (iter != g_settings.m_mapRssUrls.end()) { ((CGUIRSSControl *)control)->SetUrls(iter->second.url,iter->second.rtl); ((CGUIRSSControl *)control)->SetIntervals(iter->second.interval); } else CLog::Log(LOGERROR,"invalid rss url set referenced in skin"); } else if (type == CGUIControl::GUICONTROL_BUTTON) { control = new CGUIButtonControl( parentID, id, posX, posY, width, height, textureFocus, textureNoFocus, labelInfo); ((CGUIButtonControl *)control)->SetLabel(strLabel); ((CGUIButtonControl *)control)->SetLabel2(strLabel2); ((CGUIButtonControl *)control)->SetClickActions(clickActions); ((CGUIButtonControl *)control)->SetFocusActions(focusActions); ((CGUIButtonControl *)control)->SetUnFocusActions(unfocusActions); } else if (type == CGUIControl::GUICONTROL_TOGGLEBUTTON) { control = new CGUIToggleButtonControl( parentID, id, posX, posY, width, height, textureFocus, textureNoFocus, textureAltFocus, textureAltNoFocus, labelInfo); ((CGUIToggleButtonControl *)control)->SetLabel(strLabel); ((CGUIToggleButtonControl *)control)->SetAltLabel(altLabel); ((CGUIToggleButtonControl *)control)->SetClickActions(clickActions); ((CGUIToggleButtonControl *)control)->SetAltClickActions(altclickActions); ((CGUIToggleButtonControl *)control)->SetFocusActions(focusActions); ((CGUIToggleButtonControl *)control)->SetUnFocusActions(unfocusActions); ((CGUIToggleButtonControl *)control)->SetToggleSelect(iToggleSelect); } else if (type == CGUIControl::GUICONTROL_CHECKMARK) { control = new CGUICheckMarkControl( parentID, id, posX, posY, width, height, textureCheckMark, textureCheckMarkNF, checkWidth, checkHeight, labelInfo); ((CGUICheckMarkControl *)control)->SetLabel(strLabel); } else if (type == CGUIControl::GUICONTROL_RADIO) { control = new CGUIRadioButtonControl( parentID, id, posX, posY, width, height, textureFocus, textureNoFocus, labelInfo, textureRadioOn, textureRadioOff); ((CGUIRadioButtonControl *)control)->SetLabel(strLabel); ((CGUIRadioButtonControl *)control)->SetRadioDimensions(radioPosX, radioPosY, radioWidth, radioHeight); ((CGUIRadioButtonControl *)control)->SetToggleSelect(iToggleSelect); ((CGUIRadioButtonControl *)control)->SetClickActions(clickActions); ((CGUIRadioButtonControl *)control)->SetFocusActions(focusActions); ((CGUIRadioButtonControl *)control)->SetUnFocusActions(unfocusActions); } else if (type == CGUIControl::GUICONTROL_MULTISELECT) { CGUIInfoLabel label; if (infoLabels.size()) label = infoLabels[0]; control = new CGUIMultiSelectTextControl( parentID, id, posX, posY, width, height, textureFocus, textureNoFocus, labelInfo, label); } else if (type == CGUIControl::GUICONTROL_SPIN) { control = new CGUISpinControl( parentID, id, posX, posY, width, height, textureUp, textureDown, textureUpFocus, textureDownFocus, labelInfo, iType); ((CGUISpinControl *)control)->SetReverse(bReverse); if (iType == SPIN_CONTROL_TYPE_INT) { ((CGUISpinControl *)control)->SetRange(iMin, iMax); } else if (iType == SPIN_CONTROL_TYPE_PAGE) { ((CGUISpinControl *)control)->SetRange(iMin, iMax); ((CGUISpinControl *)control)->SetShowRange(true); ((CGUISpinControl *)control)->SetReverse(false); ((CGUISpinControl *)control)->SetShowOnePage(showOnePage); } else if (iType == SPIN_CONTROL_TYPE_FLOAT) { ((CGUISpinControl *)control)->SetFloatRange(fMin, fMax); ((CGUISpinControl *)control)->SetFloatInterval(fInterval); } } else if (type == CGUIControl::GUICONTROL_SLIDER) { control = new CGUISliderControl( parentID, id, posX, posY, width, height, textureBar, textureNib, textureNibFocus, SPIN_CONTROL_TYPE_TEXT); ((CGUISliderControl *)control)->SetInfo(singleInfo); ((CGUISliderControl *)control)->SetAction(action); } else if (type == CGUIControl::GUICONTROL_SETTINGS_SLIDER) { labelInfo.align |= XBFONT_CENTER_Y; // always center text vertically control = new CGUISettingsSliderControl( parentID, id, posX, posY, width, height, sliderWidth, sliderHeight, textureFocus, textureNoFocus, textureBar, textureNib, textureNibFocus, labelInfo, SPIN_CONTROL_TYPE_TEXT); ((CGUISettingsSliderControl *)control)->SetText(strLabel); ((CGUISettingsSliderControl *)control)->SetInfo(singleInfo); } else if (type == CGUIControl::GUICONTROL_SCROLLBAR) { control = new CGUIScrollBar( parentID, id, posX, posY, width, height, textureBackground, textureBar, textureBarFocus, textureNib, textureNibFocus, orientation, showOnePage); } else if (type == CGUIControl::GUICONTROL_PROGRESS) { control = new CGUIProgressControl( parentID, id, posX, posY, width, height, textureBackground, textureLeft, textureMid, textureRight, textureOverlay, bReveal); ((CGUIProgressControl *)control)->SetInfo(singleInfo); } else if (type == CGUIControl::GUICONTROL_IMAGE) { if (strType == "largeimage") texture.useLarge = true; // use a bordered texture if we have <bordersize> or <bordertexture> specified. if (borderTexture.filename.IsEmpty() && borderStr.IsEmpty()) control = new CGUIImage( parentID, id, posX, posY, width, height, texture); else control = new CGUIBorderedImage( parentID, id, posX, posY, width, height, texture, borderTexture, borderSize); #ifdef PRE_SKIN_VERSION_9_10_COMPATIBILITY if (insideContainer && textureFile.IsConstant()) aspect.ratio = CAspectRatio::AR_STRETCH; #endif ((CGUIImage *)control)->SetInfo(textureFile); ((CGUIImage *)control)->SetAspectRatio(aspect); ((CGUIImage *)control)->SetCrossFade(fadeTime); } else if (type == CGUIControl::GUICONTROL_MULTI_IMAGE) { control = new CGUIMultiImage( parentID, id, posX, posY, width, height, texture, timePerImage, fadeTime, randomized, loop, timeToPauseAtEnd); ((CGUIMultiImage *)control)->SetInfo(texturePath); ((CGUIMultiImage *)control)->SetAspectRatio(aspect); } else if (type == CGUIControl::GUICONTAINER_LIST) { control = new CGUIListContainer(parentID, id, posX, posY, width, height, orientation, scrollTime, preloadItems); ((CGUIListContainer *)control)->LoadLayout(pControlNode); ((CGUIListContainer *)control)->LoadContent(pControlNode); ((CGUIListContainer *)control)->SetType(viewType, viewLabel); ((CGUIListContainer *)control)->SetPageControl(pageControl); ((CGUIListContainer *)control)->SetRenderOffset(offset); } else if (type == CGUIControl::GUICONTAINER_WRAPLIST) { control = new CGUIWrappingListContainer(parentID, id, posX, posY, width, height, orientation, scrollTime, preloadItems, focusPosition); ((CGUIWrappingListContainer *)control)->LoadLayout(pControlNode); ((CGUIWrappingListContainer *)control)->LoadContent(pControlNode); ((CGUIWrappingListContainer *)control)->SetType(viewType, viewLabel); ((CGUIWrappingListContainer *)control)->SetPageControl(pageControl); ((CGUIWrappingListContainer *)control)->SetRenderOffset(offset); } else if (type == CGUIControl::GUICONTAINER_EPGGRID) { control = new CGUIEPGGridContainer(parentID, id, posX, posY, width, height, orientation, scrollTime, preloadItems, timeBlocks, rulerUnit); ((CGUIEPGGridContainer *)control)->LoadLayout(pControlNode); // ((CGUIEPGGridContainer *)control)->LoadContent(pControlNode); /// } else if (type == CGUIControl::GUICONTAINER_FIXEDLIST) { control = new CGUIFixedListContainer(parentID, id, posX, posY, width, height, orientation, scrollTime, preloadItems, focusPosition, iMovementRange); ((CGUIFixedListContainer *)control)->LoadLayout(pControlNode); ((CGUIFixedListContainer *)control)->LoadContent(pControlNode); ((CGUIFixedListContainer *)control)->SetType(viewType, viewLabel); ((CGUIFixedListContainer *)control)->SetPageControl(pageControl); ((CGUIFixedListContainer *)control)->SetRenderOffset(offset); } else if (type == CGUIControl::GUICONTAINER_PANEL) { control = new CGUIPanelContainer(parentID, id, posX, posY, width, height, orientation, scrollTime, preloadItems); ((CGUIPanelContainer *)control)->LoadLayout(pControlNode); ((CGUIPanelContainer *)control)->LoadContent(pControlNode); ((CGUIPanelContainer *)control)->SetType(viewType, viewLabel); ((CGUIPanelContainer *)control)->SetPageControl(pageControl); ((CGUIPanelContainer *)control)->SetRenderOffset(offset); } else if (type == CGUIControl::GUICONTROL_TEXTBOX) { control = new CGUITextBox( parentID, id, posX, posY, width, height, labelInfo, scrollTime); ((CGUITextBox *)control)->SetPageControl(pageControl); if (infoLabels.size()) ((CGUITextBox *)control)->SetInfo(infoLabels[0]); ((CGUITextBox *)control)->SetAutoScrolling(pControlNode); } else if (type == CGUIControl::GUICONTROL_SELECTBUTTON) { control = new CGUISelectButtonControl( parentID, id, posX, posY, width, height, textureFocus, textureNoFocus, labelInfo, textureBackground, textureLeft, textureLeftFocus, textureRight, textureRightFocus); ((CGUISelectButtonControl *)control)->SetLabel(strLabel); } else if (type == CGUIControl::GUICONTROL_MOVER) { control = new CGUIMoverControl( parentID, id, posX, posY, width, height, textureFocus, textureNoFocus); } else if (type == CGUIControl::GUICONTROL_RESIZE) { control = new CGUIResizeControl( parentID, id, posX, posY, width, height, textureFocus, textureNoFocus); } else if (type == CGUIControl::GUICONTROL_BUTTONBAR) { control = new CGUIButtonScroller( parentID, id, posX, posY, width, height, buttonGap, iNumSlots, iDefaultSlot, iMovementRange, bHorizontal, iAlpha, bWrapAround, bSmoothScrolling, textureFocus, textureNoFocus, labelInfo); ((CGUIButtonScroller *)control)->LoadButtons(pControlNode); } else if (type == CGUIControl::GUICONTROL_SPINEX) { control = new CGUISpinControlEx( parentID, id, posX, posY, width, height, spinWidth, spinHeight, labelInfo, textureFocus, textureNoFocus, textureUp, textureDown, textureUpFocus, textureDownFocus, labelInfo, iType); ((CGUISpinControlEx *)control)->SetSpinPosition(spinPosX); ((CGUISpinControlEx *)control)->SetText(strLabel); ((CGUISpinControlEx *)control)->SetReverse(bReverse); } else if (type == CGUIControl::GUICONTROL_VISUALISATION) { control = new CGUIVisualisationControl(parentID, id, posX, posY, width, height); } // things that apply to all controls if (control) { control->SetHitRect(hitRect); control->SetVisibleCondition(iVisibleCondition, allowHiddenFocus); control->SetEnableCondition(enableCondition); control->SetAnimations(animations); control->SetColorDiffuse(colorDiffuse); control->SetNavigation(up, down, left, right); control->SetTabNavigation(next,prev); control->SetNavigationActions(upActions, downActions, leftActions, rightActions); control->SetPulseOnSelect(bPulse); if (hasCamera) control->SetCamera(camera); } return control; }
void upgradeFrom3_0() { // 3.0 had process definition files in /etc/sipxpbx/process.d UtlString oldProcessDefinitionDirectory = SipXecsService::Path(SipXecsService::ConfigurationDirType, "process-old.d"); OsSysLog::add(FAC_SUPERVISOR, PRI_DEBUG,"upgradeFrom3_0: searching '%s'", oldProcessDefinitionDirectory.data() ); if ( !OsFileSystem::exists( oldProcessDefinitionDirectory) ) { return; } OsFileIterator definitions(oldProcessDefinitionDirectory); OsPath oldProcessDefinitionFile; bool okToRemoveDir = true; // set to false if any pre-4.0 process file cannot be upgraded for ( OsStatus iteratorStatus = definitions.findFirst(oldProcessDefinitionFile, OLD_PROCESS_DEFINITION_NAME_PATTERN, OsFileIterator::FILES); OS_SUCCESS == iteratorStatus; iteratorStatus = definitions.findNext(oldProcessDefinitionFile) ) { OsPath oldProcessDefinitionPath( oldProcessDefinitionDirectory +OsPath::separator +oldProcessDefinitionFile ); OsSysLog::add(FAC_SUPERVISOR, PRI_INFO,"upgradeFrom3_0: reading pre-4.0 process def '%s'", oldProcessDefinitionPath.data() ); // read the process name and the watchdog enable setting, // and enable the process if necessary TiXmlDocument processDefinitionDoc(oldProcessDefinitionPath); bool definitionValid = true; UtlString errorMsg; if ( processDefinitionDoc.LoadFile() ) { TiXmlElement *subroot = processDefinitionDoc.RootElement(); if (subroot != NULL) { bool bEnabled=false; const char *enableString = subroot->Attribute("enable"); if (enableString == NULL || strcmp(enableString, "true")==0) { bEnabled=true; } TiXmlElement* processDefElement = subroot->FirstChildElement("process_definitions"); if (processDefElement) { TiXmlNode *pGroupNode = processDefElement->FirstChild("group"); if (pGroupNode) { TiXmlElement *processElement = pGroupNode->FirstChildElement("process"); if (processElement) { const char *pMsg = processElement->Attribute("name"); UtlString processName = pMsg; // enable or disable process based on setting in old process def file SipxProcess* newProcess; if ((newProcess=SipxProcessManager::getInstance()->findProcess(processName))) { if (bEnabled) { OsSysLog::add(FAC_SUPERVISOR, PRI_NOTICE, "upgradeFrom3_0: enabling process '%s'", processName.data()); newProcess->enable(); } else { OsSysLog::add(FAC_SUPERVISOR, PRI_NOTICE, "upgradeFrom3_0: disabling process '%s'", processName.data()); newProcess->disable(); } if (OS_SUCCESS == OsFileSystem::remove(oldProcessDefinitionPath)) { OsSysLog::add(FAC_SUPERVISOR, PRI_NOTICE, "upgradeFrom3_0: removing pre-4.0 process def file '%s'", oldProcessDefinitionPath.data()); } else { OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "upgradeFrom3_0: failed to remove pre-4.0 process def file '%s'", oldProcessDefinitionPath.data()); } } else { OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "upgradeFrom3_0: could not find process '%s'", processName.data()); okToRemoveDir = false; } } else { definitionValid = false; } } else { definitionValid = false; } } else { definitionValid = false; } } else { definitionValid = false; } } else { definitionValid = false; } if ( !definitionValid ) { // Invalid document format. Log the issue and continue to the next process xml file. XmlErrorMsg(processDefinitionDoc, errorMsg); OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "upgradeFrom3_0: ignoring invalid pre-4.0 process xml file '%s' (%s)", oldProcessDefinitionFile.data(), errorMsg.data()); okToRemoveDir = false; } } // remove the old process defn directory (succeeds only if it is empty) if (OS_SUCCESS == OsFileSystem::remove(oldProcessDefinitionDirectory)) { OsSysLog::add(FAC_SUPERVISOR, PRI_NOTICE, "upgradeFrom3_0: all process data has been migrated from " "pre-4.0 process def directory '%s', " "and the directory has been deleted.", oldProcessDefinitionDirectory.data()); } else { // rmdir may fail because files still exist (e.g. editor backup files). // Log whether upgrade succeeded or not. if ( okToRemoveDir ) { OsSysLog::add(FAC_SUPERVISOR, PRI_NOTICE, "upgradeFrom3_0: all process data has been migrated from " "pre-4.0 process def directory '%s', " "and the directory may safely be deleted.", oldProcessDefinitionDirectory.data()); } else { OsSysLog::add(FAC_SUPERVISOR, PRI_WARNING, "upgradeFrom3_0: some process data could not be migrated from " "pre-4.0 process def directory '%s'. ", oldProcessDefinitionDirectory.data()); } } }
bool CGUIWindow::Load(TiXmlDocument &xmlDoc) { TiXmlElement* pRootElement = xmlDoc.RootElement(); if (strcmpi(pRootElement->Value(), "window")) { CLog::Log(LOGERROR, "file : XML file doesnt contain <window>"); return false; } // set the scaling resolution so that any control creation or initialisation can // be done with respect to the correct aspect ratio g_graphicsContext.SetScalingResolution(m_coordsRes, m_needsScaling); // Resolve any includes that may be present g_SkinInfo->ResolveIncludes(pRootElement); // now load in the skin file SetDefaults(); CGUIControlFactory::GetInfoColor(pRootElement, "backgroundcolor", m_clearBackground); CGUIControlFactory::GetMultipleString(pRootElement, "onload", m_loadActions); CGUIControlFactory::GetMultipleString(pRootElement, "onunload", m_unloadActions); CGUIControlFactory::GetHitRect(pRootElement, m_hitRect); TiXmlElement *pChild = pRootElement->FirstChildElement(); while (pChild) { CStdString strValue = pChild->Value(); if (strValue == "type" && pChild->FirstChild()) { // if we have are a window type (ie not a dialog), and we have <type>dialog</type> // then make this window act like a dialog if (!IsDialog() && strcmpi(pChild->FirstChild()->Value(), "dialog") == 0) m_isDialog = true; } else if (strValue == "previouswindow" && pChild->FirstChild()) { m_previousWindow = CButtonTranslator::TranslateWindow(pChild->FirstChild()->Value()); } else if (strValue == "defaultcontrol" && pChild->FirstChild()) { const char *always = pChild->Attribute("always"); if (always && strcmpi(always, "true") == 0) m_defaultAlways = true; m_defaultControl = atoi(pChild->FirstChild()->Value()); } else if (strValue == "visible" && pChild->FirstChild()) { CStdString condition; CGUIControlFactory::GetConditionalVisibility(pRootElement, condition); m_visibleCondition = g_infoManager.Register(condition, GetID()); } else if (strValue == "animation" && pChild->FirstChild()) { CRect rect(0, 0, (float)m_coordsRes.iWidth, (float)m_coordsRes.iHeight); CAnimation anim; anim.Create(pChild, rect, GetID()); m_animations.push_back(anim); } else if (strValue == "zorder" && pChild->FirstChild()) { m_renderOrder = atoi(pChild->FirstChild()->Value()); } else if (strValue == "coordinates") { XMLUtils::GetFloat(pChild, "posx", m_posX); XMLUtils::GetFloat(pChild, "posy", m_posY); TiXmlElement *originElement = pChild->FirstChildElement("origin"); while (originElement) { COrigin origin; originElement->QueryFloatAttribute("x", &origin.x); originElement->QueryFloatAttribute("y", &origin.y); if (originElement->FirstChild()) origin.condition = g_infoManager.Register(originElement->FirstChild()->Value(), GetID()); m_origins.push_back(origin); originElement = originElement->NextSiblingElement("origin"); } } else if (strValue == "camera") { // z is fixed pChild->QueryFloatAttribute("x", &m_camera.x); pChild->QueryFloatAttribute("y", &m_camera.y); m_hasCamera = true; } else if (strValue == "controls") { TiXmlElement *pControl = pChild->FirstChildElement(); while (pControl) { if (strcmpi(pControl->Value(), "control") == 0) { LoadControl(pControl, NULL); } pControl = pControl->NextSiblingElement(); } } else if (strValue == "allowoverlay") { bool overlay = false; if (XMLUtils::GetBoolean(pRootElement, "allowoverlay", overlay)) m_overlayState = overlay ? OVERLAY_STATE_SHOWN : OVERLAY_STATE_HIDDEN; } pChild = pChild->NextSiblingElement(); } LoadAdditionalTags(pRootElement); m_windowLoaded = true; OnWindowLoaded(); return true; }
void CMusicInfoScraper::FindAlbuminfo() { CStdString strAlbum=m_strAlbum; CStdString strHTML; m_vecAlbums.erase(m_vecAlbums.begin(), m_vecAlbums.end()); CScraperParser parser; if (!parser.Load(_P("q:\\system\\scrapers\\music\\"+m_info.strPath))) return; if (!m_info.settings.GetPluginRoot() || m_info.settings.GetSettings().IsEmpty()) { m_info.settings.LoadSettingsXML(_P("q:\\system\\scrapers\\music\\"+m_info.strPath)); m_info.settings.SaveFromDefault(); } parser.m_param[0] = strAlbum; parser.m_param[1] = m_strArtist; CUtil::URLEncode(parser.m_param[0]); CUtil::URLEncode(parser.m_param[1]); CScraperUrl scrURL; scrURL.ParseString(parser.Parse("CreateAlbumSearchUrl")); if (!CScraperUrl::Get(scrURL.m_url[0], strHTML, m_http) || strHTML.size() == 0) { CLog::Log(LOGERROR, "%s: Unable to retrieve web site",__FUNCTION__); return; } parser.m_param[0] = strHTML; CStdString strXML = parser.Parse("GetAlbumSearchResults",&m_info.settings); if (strXML.IsEmpty()) { CLog::Log(LOGERROR, "%s: Unable to parse web site",__FUNCTION__); return; } if (strXML.Find("encoding=\"utf-8\"") < 0) g_charsetConverter.stringCharsetToUtf8(strXML); // ok, now parse the xml file TiXmlDocument doc; doc.Parse(strXML.c_str(),0,TIXML_ENCODING_UTF8); if (!doc.RootElement()) { CLog::Log(LOGERROR, "%s: Unable to parse xml",__FUNCTION__); return; } TiXmlHandle docHandle( &doc ); TiXmlElement* album = docHandle.FirstChild( "results" ).FirstChild( "entity" ).Element(); if (!album) return; while (album) { TiXmlNode* title = album->FirstChild("title"); TiXmlElement* link = album->FirstChildElement("url"); TiXmlNode* artist = album->FirstChild("artist"); TiXmlNode* year = album->FirstChild("year"); if (title && title->FirstChild()) { CStdString strTitle = title->FirstChild()->Value(); CStdString strArtist; CStdString strAlbumName; if (artist && artist->FirstChild()) { strArtist = artist->FirstChild()->Value(); strAlbumName.Format("%s - %s",strArtist.c_str(),strTitle.c_str()); } else strAlbumName = strTitle; if (year && year->FirstChild()) strAlbumName.Format("%s (%s)",strAlbumName.c_str(),year->FirstChild()->Value()); CScraperUrl url; if (!link) url.ParseString(scrURL.m_xml); while (link && link->FirstChild()) { url.ParseElement(link); link = link->NextSiblingElement("url"); } CMusicAlbumInfo newAlbum(strTitle, strArtist, strAlbumName, url); m_vecAlbums.push_back(newAlbum); } album = album->NextSiblingElement(); } if (m_vecAlbums.size()>0) m_bSuccessfull=true; return; }
bool CRSSDirectory::GetDirectory(const CStdString& path, CFileItemList &items) { CStdString strPath(path); URIUtils::RemoveSlashAtEnd(strPath); std::map<CStdString,CDateTime>::iterator it; items.SetPath(strPath); CSingleLock lock(m_section); if ((it=m_cache.find(strPath)) != m_cache.end()) { if (it->second > CDateTime::GetCurrentDateTime() && items.Load()) return true; m_cache.erase(it); } lock.Leave(); CXBMCTinyXML xmlDoc; if (!xmlDoc.LoadFile(strPath)) { CLog::Log(LOGERROR,"failed to load xml from <%s>. error: <%d>", strPath.c_str(), xmlDoc.ErrorId()); return false; } if (xmlDoc.Error()) { CLog::Log(LOGERROR,"error parsing xml doc from <%s>. error: <%d>", strPath.c_str(), xmlDoc.ErrorId()); return false; } TiXmlElement* rssXmlNode = xmlDoc.RootElement(); if (!rssXmlNode) return false; TiXmlHandle docHandle( &xmlDoc ); TiXmlElement* channelXmlNode = docHandle.FirstChild( "rss" ).FirstChild( "channel" ).Element(); if (channelXmlNode) ParseItem(&items, channelXmlNode, path); else return false; TiXmlElement* child = NULL; for (child = channelXmlNode->FirstChildElement("item"); child; child = child->NextSiblingElement()) { // Create new item, CFileItemPtr item(new CFileItem()); ParseItem(item.get(), child, path); item->SetProperty("isrss", "1"); if (!item->GetPath().IsEmpty()) items.Add(item); } items.AddSortMethod(SORT_METHOD_UNSORTED , 231, LABEL_MASKS("%L", "%D", "%L", "")); // FileName, Duration | Foldername, empty items.AddSortMethod(SORT_METHOD_LABEL , 551, LABEL_MASKS("%L", "%D", "%L", "")); // FileName, Duration | Foldername, empty items.AddSortMethod(SORT_METHOD_SIZE , 553, LABEL_MASKS("%L", "%I", "%L", "%I")); // FileName, Size | Foldername, Size items.AddSortMethod(SORT_METHOD_DATE , 552, LABEL_MASKS("%L", "%J", "%L", "%J")); // FileName, Date | Foldername, Date CDateTime time = CDateTime::GetCurrentDateTime(); int mins = 60; TiXmlElement* ttl = docHandle.FirstChild("rss").FirstChild("ttl").Element(); if (ttl) mins = strtol(ttl->FirstChild()->Value(),NULL,10); time += CDateTimeSpan(0,0,mins,0); items.SetPath(strPath); items.Save(); CSingleLock lock2(m_section); m_cache.insert(make_pair(strPath,time)); return true; }
void CSettingsManager::read_SettingsXML() { TiXmlDocument xmlDoc; if(!xmlDoc.LoadFile(m_XMLFilename)) { KODI->Log(LOG_NOTICE, "No initial settings XML file found."); return; } TiXmlElement *pRootElement = xmlDoc.RootElement(); if(!pRootElement) { KODI->Log(LOG_NOTICE, "Settings XML file is empty."); return; } string mainCategory = pRootElement->Value(); for(TiXmlNode *pGroupNode = pRootElement->FirstChild(); pGroupNode != NULL; pGroupNode = pRootElement->IterateChildren(pGroupNode)) { if(pGroupNode->ValueStr() == "settings_group") { ATTRIBUTES_LIST groupAttributesList; if(pGroupNode && pGroupNode->Type() == TiXmlNode::TINYXML_ELEMENT) { getAttributesAsList(pGroupNode->ToElement(), groupAttributesList); } if(pGroupNode && pGroupNode->Type() == TiXmlNode::TINYXML_ELEMENT && groupAttributesList.size() == 2 && pGroupNode->ValueStr() == "settings_group") { string subCategory = ""; string groupName = ""; for(ATTRIBUTES_LIST::iterator iter = groupAttributesList.begin(); iter != groupAttributesList.end(); iter++) { if(iter->first == "sub_category") { subCategory = iter->second; } if(iter->first == "group_name") { groupName = iter->second; } } for(TiXmlNode *pKeyNode = pGroupNode->FirstChild(); pKeyNode != NULL; pKeyNode = pGroupNode->IterateChildren(pKeyNode)) { if(pKeyNode && pKeyNode->Type() == TiXmlNode::TINYXML_ELEMENT && pKeyNode->ValueStr() == "setting") { ATTRIBUTES_LIST settingAttributesList; if(getAttributesAsList(pKeyNode->ToElement(), settingAttributesList) == 2) { string key = ""; ISettingsElement::SettingsTypes type = ISettingsElement::UNKNOWN_SETTING; string value = ""; for(ATTRIBUTES_LIST::iterator iter = settingAttributesList.begin(); iter != settingAttributesList.end(); iter++) { if(iter->first == "key") { key = iter->second; } else { type = CSettingsHelpers::TranslateTypeStrToEnum(iter->first); value = iter->second; } } ISettingsElement *setting = find_Setting(mainCategory, subCategory, groupName, key); if(setting && setting->get_Type() == type) { switch(type) { case ISettingsElement::STRING_SETTING: STRING_SETTINGS(setting)->set_Setting(value); break; case ISettingsElement::UNSIGNED_INT_SETTING: { unsigned int val = stringToVal<unsigned int>(value); UNSIGNED_INT_SETTINGS(setting)->set_Setting(val); } break; case ISettingsElement::INT_SETTING: { int val = stringToVal<int>(value); INT_SETTINGS(setting)->set_Setting(val); } break; case ISettingsElement::FLOAT_SETTING: { float val = stringToVal<float>(value); FLOAT_SETTINGS(setting)->set_Setting(val); } break; case ISettingsElement::DOUBLE_SETTING: { double val = stringToVal<double>(value); DOUBLE_SETTINGS(setting)->set_Setting(val); } break; case ISettingsElement::BOOL_SETTING: if(value == "true" || value == "TRUE" || value == "True") { bool val = true; BOOL_SETTINGS(setting)->set_Setting(val); } else if(value == "false" || value == "FALSE" || value == "False") { bool val = false; BOOL_SETTINGS(setting)->set_Setting(val); } else { KODI->Log(LOG_ERROR, "CSettingsManager: Failed reading bool setting"); } break; default: KODI->Log(LOG_ERROR, "CSettingsManager: Unknown settings type!"); break; } } else { KODI->Log(LOG_ERROR, "CSettingsManager: Read settings element does not match the created settings element type!"); } } } } } } } }
void CScraperParser::ParseExpression(const std::string& input, std::string& dest, TiXmlElement* element, bool bAppend) { std::string strOutput = XMLUtils::GetAttribute(element, "output"); TiXmlElement* pExpression = element->FirstChildElement("expression"); if (pExpression) { bool bInsensitive=true; const char* sensitive = pExpression->Attribute("cs"); if (sensitive) if (stricmp(sensitive,"yes") == 0) bInsensitive=false; // match case sensitive CRegExp::utf8Mode eUtf8 = CRegExp::autoUtf8; const char* const strUtf8 = pExpression->Attribute("utf8"); if (strUtf8) { if (stricmp(strUtf8, "yes") == 0) eUtf8 = CRegExp::forceUtf8; else if (stricmp(strUtf8, "no") == 0) eUtf8 = CRegExp::asciiOnly; else if (stricmp(strUtf8, "auto") == 0) eUtf8 = CRegExp::autoUtf8; } CRegExp reg(bInsensitive, eUtf8); std::string strExpression; if (pExpression->FirstChild()) strExpression = pExpression->FirstChild()->Value(); else strExpression = "(.*)"; ReplaceBuffers(strExpression); ReplaceBuffers(strOutput); if (!reg.RegComp(strExpression.c_str())) { return; } bool bRepeat = false; const char* szRepeat = pExpression->Attribute("repeat"); if (szRepeat) if (stricmp(szRepeat,"yes") == 0) bRepeat = true; const char* szClear = pExpression->Attribute("clear"); if (szClear) if (stricmp(szClear,"yes") == 0) dest=""; // clear no matter if regexp fails bool bClean[MAX_SCRAPER_BUFFERS]; GetBufferParams(bClean,pExpression->Attribute("noclean"),true); bool bTrim[MAX_SCRAPER_BUFFERS]; GetBufferParams(bTrim,pExpression->Attribute("trim"),false); bool bFixChars[MAX_SCRAPER_BUFFERS]; GetBufferParams(bFixChars,pExpression->Attribute("fixchars"),false); bool bEncode[MAX_SCRAPER_BUFFERS]; GetBufferParams(bEncode,pExpression->Attribute("encode"),false); int iOptional = -1; pExpression->QueryIntAttribute("optional",&iOptional); int iCompare = -1; pExpression->QueryIntAttribute("compare",&iCompare); if (iCompare > -1) StringUtils::ToLower(m_param[iCompare-1]); std::string curInput = input; for (int iBuf=0;iBuf<MAX_SCRAPER_BUFFERS;++iBuf) { if (bClean[iBuf]) InsertToken(strOutput,iBuf+1,"!!!CLEAN!!!"); if (bTrim[iBuf]) InsertToken(strOutput,iBuf+1,"!!!TRIM!!!"); if (bFixChars[iBuf]) InsertToken(strOutput,iBuf+1,"!!!FIXCHARS!!!"); if (bEncode[iBuf]) InsertToken(strOutput,iBuf+1,"!!!ENCODE!!!"); } int i = reg.RegFind(curInput.c_str()); while (i > -1 && (i < (int)curInput.size() || curInput.empty())) { if (!bAppend) { dest = ""; bAppend = true; } std::string strCurOutput=strOutput; if (iOptional > -1) // check that required param is there { char temp[12]; sprintf(temp,"\\%i",iOptional); std::string szParam = reg.GetReplaceString(temp); CRegExp reg2; reg2.RegComp("(.*)(\\\\\\(.*\\\\2.*)\\\\\\)(.*)"); int i2=reg2.RegFind(strCurOutput.c_str()); while (i2 > -1) { std::string szRemove(reg2.GetMatch(2)); int iRemove = szRemove.size(); int i3 = strCurOutput.find(szRemove); if (!szParam.empty()) { strCurOutput.erase(i3+iRemove,2); strCurOutput.erase(i3,2); } else strCurOutput.replace(strCurOutput.begin()+i3,strCurOutput.begin()+i3+iRemove+2,""); i2 = reg2.RegFind(strCurOutput.c_str()); } } int iLen = reg.GetFindLen(); // nasty hack #1 - & means \0 in a replace string StringUtils::Replace(strCurOutput, "&","!!!AMPAMP!!!"); std::string result = reg.GetReplaceString(strCurOutput.c_str()); if (!result.empty()) { std::string strResult(result); StringUtils::Replace(strResult, "!!!AMPAMP!!!","&"); Clean(strResult); ReplaceBuffers(strResult); if (iCompare > -1) { std::string strResultNoCase = strResult; StringUtils::ToLower(strResultNoCase); if (strResultNoCase.find(m_param[iCompare-1]) != std::string::npos) dest += strResult; } else dest += strResult; } if (bRepeat && iLen > 0) { curInput.erase(0,i+iLen>(int)curInput.size()?curInput.size():i+iLen); i = reg.RegFind(curInput.c_str()); } else i = -1; } } }