bool ProfileSelectorWeightedFactory::setFromXML(ProfileSelector* pSel, TiXmlElement* node,
                                                const std::string& specFldr) const {
  ProfileSelectorWeighted* sel = dynamic_cast<ProfileSelectorWeighted*>(pSel);
  assert(sel != 0x0 &&
         "Trying to set attributes of a weighted profile selector "
         "element on an incompatible object");
  if (!ProfileSelectorFactory::setFromXML(sel, node, specFldr)) return false;

  // Parse each of the names.
  for (TiXmlElement* child = node->FirstChildElement("Profile"); child;
       child = child->NextSiblingElement()) {
    const char* nameCStr = child->Attribute("name");
    if (nameCStr == 0x0) {
      logger << Logger::ERR_MSG << "The AgentProfile referred to on line " << child->Row()
             << " is missing the required \"name\" attribute.";
      return false;
    }

    double weight;
    if (!child->Attribute("weight", &weight)) {
      logger << Logger::ERR_MSG << "The AgentProfile referred to on line " << child->Row()
             << " is missing the required \"weight\" attribute.";
      return false;
    }
    sel->_profile_specs.emplace_back(nameCStr, static_cast<float>(weight));
  }

  return true;
}
Beispiel #2
0
RobotInterface::ParamList RobotInterface::XMLReader::Private::readParamListTag(TiXmlElement* paramListElem)
{
    if (paramListElem->ValueStr().compare("paramlist") != 0) {
        SYNTAX_ERROR(paramListElem->Row()) << "Expected \"paramlist\". Found" << paramListElem->ValueStr();
    }

    ParamList params;
    Param mainparam;

    if (paramListElem->QueryStringAttribute("name", &mainparam.name()) != TIXML_SUCCESS) {
        SYNTAX_ERROR(paramListElem->Row()) << "\"paramlist\" element should contain the \"name\" attribute";
    }

    params.push_back(mainparam);

    // yDebug() << "Found paramlist [" << params.at(0).name() << "]";

    for (TiXmlElement* childElem = paramListElem->FirstChildElement(); childElem != 0; childElem = childElem->NextSiblingElement()) {
        if (childElem->ValueStr().compare("elem") != 0) {
            SYNTAX_ERROR(childElem->Row()) << "Expected \"elem\". Found" << childElem->ValueStr();
        }

        Param childParam;

        if (childElem->QueryStringAttribute("name", &childParam.name()) != TIXML_SUCCESS) {
            SYNTAX_ERROR(childElem->Row()) << "\"elem\" element should contain the \"name\" attribute";
        }

        const char *valueText = childElem->GetText();
        if (!valueText) {
            SYNTAX_ERROR(childElem->Row()) << "\"elem\" element should have a value [ \"name\" = " << childParam.name() << "]";
        }
        childParam.value() = valueText;

        params.push_back(childParam);
    }

    if (params.empty()) {
        SYNTAX_ERROR(paramListElem->Row()) << "\"paramlist\" cannot be empty";
    }

    // +1 skips the first element, that is the main param
    for (ParamList::iterator it = params.begin() + 1; it != params.end(); ++it) {
        Param &param = *it;
        params.at(0).value() += (params.at(0).value().empty() ? "(" : " ") + param.name();
    }
    params.at(0).value() += ")";

    // yDebug() << params;
    return params;
}
Beispiel #3
0
		ObstacleVertexList ExplicitObstacleSetFactory::parseObstacle( TiXmlElement * node) const {

			int iVal;
			// TODO: Simply eliminate the bounding box obstacle -- it is basically
			//	just ignored.
			bool bb = false;
			if ( node->Attribute( "boundingbox", &iVal ) ) {
				// Skip bounding box obstacles, but treat it as normal
				bb = (iVal != 0);
				assert(!bb && "Bounding Boxes are depreciated!");
			}
			ObstacleVertexList vList;
			vList.closed = false;
			if ( node->Attribute( "closed", &iVal ) ) {
				vList.closed = (iVal != 0);
			}

			double dVal;
			bool valid = true;
			
			for ( TiXmlElement * vert = node->FirstChildElement(); vert; vert = vert->NextSiblingElement() ) {
				if ( vert->ValueStr() == "Vertex") {
					float p_x = 0;
					float p_y = 0;
					if ( vert->Attribute( "p_x", &dVal) ) {
						p_x = (float)dVal;
					} else {
						valid = false;
					}
					if ( vert->Attribute( "p_y", &dVal) ) {
						p_y = (float)dVal;
					} else {
						valid = false;
					}

					if ( ! valid ) {
						logger << Logger::ERR_MSG << "Obstacle vertex on line " << vert->Row() << " is missing the full x- and y-position specification.";
						throw ObstacleSetFatalException("Obstacle vertex missing full specification");

					}
					vList.vertices.push_back( Vector2( p_x, p_y ) );
				}
				else {
					logger << Logger::WARN_MSG << "Encountered unexpected tag inside an obstacle definition on line " << vert->Row() << ": " << vert->ValueStr() << ".  It will be ignored.";
				}

				if ( ! valid ) {
					logger << Logger::ERR_MSG << "Incomplete obstacle definition on line " << node->Row() << ".";
					throw ObstacleSetFatalException("Incomplete obstacle definition");
				}
			}

			return vList;
		};
Beispiel #4
0
int SceneLoader::load(string scene_file, Scene** scene, int xRes, int yRes) {
    TiXmlDocument doc(scene_file);
    if ( !doc.LoadFile() ) {
        Logger::log(LOG_ERROR) << "Scene loading failed : " << scene_file << endl;
        Logger::log(LOG_ERROR) << "Error #" << doc.ErrorId() << " : " << doc.ErrorDesc() << endl;
        return -1;
    } else {
        Logger::log(LOG_INFO) << "Start loading scene : " << scene_file << endl;
        Uint32 initial_tick = SDL_GetTicks();

        list<Object*> objects;
        list<Light*> lights;
        set<Material*> materials;
        AmbientLight ambientLight;
        Camera* camera=0;
        TiXmlElement* tmp_node = 0;

        TiXmlHandle hdl(&doc);
        TiXmlElement* node = hdl.FirstChildElement().FirstChildElement().Element();
        if (node == NULL) {
            Logger::log(LOG_ERROR)<<"Error on top of the file"<<endl;
            return -1;
        }

        while ( node ) {
            string nodeName(node->Value());
            if ( nodeName.compare("camera")==0 ) {
                VEC3F position, target, normal;
                float w = 8, d = 35;

                tmp_node = node->FirstChildElement("position");
                if (tmp_node == NULL) {
                    Logger::log(LOG_ERROR)<<"Missing <position> near line "<<node->Row()<<endl;
                } else {
                    position = readVec3Float(tmp_node);
                }

                tmp_node = node->FirstChildElement("target");
                if (tmp_node == NULL) {
                    Logger::log(LOG_ERROR)<<"Missing <target> near line "<<node->Row()<<endl;
                } else {
                    target = readVec3Float(tmp_node);
                }

                tmp_node = node->FirstChildElement("normal");
                if (tmp_node == NULL) {
                    Logger::log(LOG_ERROR)<<"Missing <normal> near line "<<node->Row()<<endl;
                } else {
                    normal = readVec3Float(tmp_node);
                }

                tmp_node = node->FirstChildElement("viewplane");
                if (tmp_node == NULL) {
                    Logger::log(LOG_ERROR)<<"Missing <viewplane> near line "<<node->Row()<<endl;
                } else {
                    tmp_node->QueryFloatAttribute("w", &w);
                    tmp_node->QueryFloatAttribute("d", &d);
                }

                camera = new Camera(position,
                                    target-position,
                                    normal,
                                    w, d,
                                    xRes, yRes,
                                    Settings::getAsFloat("camera_translation_factor"),
                                    Settings::getAsFloat("camera_rotation_angle"));
            } else if ( nodeName.compare("directionalLight")==0 ) {
                Color color;
                VEC3F direction;

                tmp_node = node->FirstChildElement("color");
                if (tmp_node == NULL) {
                    Logger::log(LOG_ERROR)<<"Missing <color> near line "<<node->Row()<<endl;
                } else {
                    color = readColor(tmp_node);
                }

                tmp_node = node->FirstChildElement("direction");
                if (tmp_node == NULL) {
                    Logger::log(LOG_ERROR)<<"Missing <direction> near line "<<node->Row()<<endl;
                } else {
                    direction = readVec3Float(tmp_node);
                }
                DirectionalLight *dirLight = new DirectionalLight(color, direction.normalize()); // !!!!!!!!!! NEEDS TO BE DESTROYED
                lights.push_back(dirLight);
            } else if ( nodeName.compare("pointLight")==0 ) {
                Color color;
                VEC3F point;

                tmp_node = node->FirstChildElement("color");
                if (tmp_node == NULL) {
                    Logger::log(LOG_ERROR)<<"Missing <color> near line "<<node->Row()<<endl;
                } else {
                    color = readColor(tmp_node);
                }

                tmp_node = node->FirstChildElement("point");
                if (tmp_node == NULL) {
                    Logger::log(LOG_ERROR)<<"Missing <point> near line "<<node->Row()<<endl;
                } else {
                    point = readVec3Float(tmp_node);
                }
                PointLight *pointLight = new PointLight(color, point); // !!!!!!!!!! NEEDS TO BE DESTROYED
                lights.push_back(pointLight);
            } else if ( nodeName.compare("ambientLight")==0 ) {
                Color color;

                tmp_node = node->FirstChildElement("color");
                if (tmp_node == NULL) {
                    Logger::log(LOG_ERROR)<<"Missing <color> near line "<<node->Row()<<endl;
                } else {
                    color = readColor(tmp_node);
                }

                ambientLight = AmbientLight(color);
            } else if ( nodeName.compare("object")==0 ) {
                Material* material = 0;

                tmp_node = node->FirstChildElement("material");
                if (tmp_node == NULL) {
                    Logger::log(LOG_ERROR)<<"Missing <material> near line "<<node->Row()<<endl;
                } else {
                    material = readMaterial(tmp_node);
                    if (material != NULL) {
                        if (materials.count(material) == 0) {
                            materials.insert(material);
                        }
                    }
                }

                tmp_node = node->FirstChildElement("shape");
                if (tmp_node == NULL) {
                    Logger::log(LOG_ERROR)<<"Missing <shape> near line "<<node->Row()<<endl;
                } else {
                    readShape(tmp_node->FirstChildElement(), &objects, material);
                }
            } else {
                Logger::log(LOG_ERROR)<<"Unknown primary node line "<<node->Row()<<endl;
            }

            node = node->NextSiblingElement();
        }

        float loading_time=(SDL_GetTicks()-initial_tick)/(float)1000;
        Logger::log(LOG_INFO) << "Scene loaded ("<<(int) objects.size()<<" objects) ("
                              << loading_time << " s)" << endl;

        *scene = new Scene(objects,lights,materials,ambientLight,camera);

        return 0;
    }
}
Beispiel #5
0
    bool LoggingSystem::LoadLoggerListenerDefs()
    {
        using namespace LogAppenders;

        const TiXmlElement* config = Config::GetInstance().GetSection("LoggingSystem");
        if (config == NULL) return false;
        
        TiXmlHandle doc((TiXmlNode*)config);
        TiXmlNode* node = doc.FirstChildElement("Appenders").Child(0).Node();
        while (node && node->Type() != TiXmlNode::ELEMENT)
            node = node->NextSibling();

        if (node == NULL) return false;

        TiXmlElement* loggerDef = node->ToElement();
        for( loggerDef; loggerDef; loggerDef=loggerDef->NextSiblingElement())
        {
            const char* type = loggerDef->Value();
            bool created = false;
            bool error = false;
            if (!XmlReadBool(loggerDef, "enabled", true)) continue;
            for (uint i = 0; i < sizeof(gAppendersDefenitions) / sizeof(AppenderDefenition); i++)
            {
                if (strcmp(type, gAppendersDefenitions[i].Type) != 0) continue;
                LogAppender* listener = NULL;
                try
                {
                    listener = gAppendersDefenitions[i].FactoryFunction(loggerDef);
                    if (listener == NULL)
                    { 
                        std::wostringstream os;
                        os << L"Invalid log appender defenition <" << loggerDef->Value() << L" ... /> in config.xml at line " << loggerDef->Row();
                        Message(os.str().c_str(), LOG_WARN, L"System.LoggingSystem");
                        continue;
                    }

                    const char* thresholdAttr = loggerDef->Attribute("threshold");
                    LogLevel threshold = LOG_TRACE;
                    if (thresholdAttr)
                    {
                        if (strcmp(thresholdAttr, "trace") == 0) 
                            threshold = LOG_TRACE;
                        else if (strcmp(thresholdAttr, "debug") == 0) 
                            threshold = LOG_DEBUG;
                        else if (strcmp(thresholdAttr, "info") == 0) 
                            threshold = LOG_INFO;
                        else if (strcmp(thresholdAttr, "warn") == 0) 
                            threshold = LOG_WARN;
                        else if (strcmp(thresholdAttr, "error") == 0) 
                            threshold = LOG_ERROR;
                    }

                    const char* source = loggerDef->Attribute("sources");
                    if (source == NULL)
                        AddAppender(listener);
                    else
                        AddAppender(listener, threshold, ToUTF16(source));
                    listener->Release();
                    created = true;
                    break;
                }
                catch (Exception& e)
                {
                    if (listener != NULL) RemoveAppender(listener);
                    std::wostringstream os;
                    os << L"Failed to create log appender <" << loggerDef->Value() << L" ... /> in config.xml at line " << loggerDef->Row() << L": " 
                        << e.GetFullDescription();
                    Message(os.str().c_str(), LOG_WARN, L"System.LoggingSystem");
                    error = true; 
                    break;
                }
            }
            if (!created && !error)
            {
                std::wostringstream os;
                os << L"Unrecognized log appender <" << loggerDef->Value() << L" ... /> in config.xml at line " << loggerDef->Row() << L".";
                Message(os.str().c_str(), LOG_WARN, L"System.LoggingSystem");
            }
        }

        return true;
    }
Beispiel #6
0
	/// Visit an element.
	virtual bool VisitExit( const TiXmlElement& element )		
	{
		std::string str = element.Value();
		std::string top = mStack.top();
		if(str != top)
		{
			OUTSTRING("... [%s]/[%s]: before element has not exit : %d\n", fileName.c_str(), element.Value(), element.Row());
		}
        mStack.pop();
		return true; 
	}
Beispiel #7
0
bool Scene::readXml(TiXmlElement* e)
{
	string objName;

	TiXmlElement* child = e->FirstChildElement();
	while(child != NULL)
	{
		if(child->ValueStr() == "pixel")
		{
			if((objName = Xml::getAttrString(child, "name")) != "")
			{
				Pixel* p = new Pixel(objName, getOscRootAddress());
				p->loadXml(child);
				addObject(p);
				
				LOG_DEBUG << "Scene \"" << _name << "\": Loaded pixel \"" << objName << "\" \""
						  << p->getOscRootAddress() << "\"" << std::endl;
			}
			else
			{
				LOG_WARN << "Scene \"" << _name << "\": cannot load pixel without name, line "
						 << child->Row() << endl;
			}
		}

		else if(child->ValueStr() == "line")
		{
			if((objName = Xml::getAttrString(child, "name")) != "")
			{						  
				Line* l = new Line(objName, getOscRootAddress());
				l->loadXml(child);
				addObject(l);
				
				LOG_DEBUG << "Scene \"" << _name << "\": Loaded line \"" << objName << "\" \""
						  << l->getOscRootAddress() << "\"" << std::endl;
			}
			else
			{
				LOG_WARN << "Scene \"" << _name << "\": cannot load line without name, line "
						 << child->Row() << endl;
			}
		}

		else if(child->ValueStr() == "rect")
		{
			if((objName = Xml::getAttrString(child, "name")) != "")
			{
				Rect* r = new Rect(objName, getOscRootAddress());
				r->loadXml(child);
				addObject(r);
				
				LOG_DEBUG << "Scene \"" << _name << "\": Loaded rect \"" << objName << "\" \""
						  << r->getOscRootAddress() << "\"" << std::endl;
			}
			else
			{
				LOG_WARN << "Scene \"" << _name << "\": cannot load rect without name, line "
						 << child->Row() << endl;
			}
		}

		else if(child->ValueStr() == "bitmap")
		{
			if((objName = Xml::getAttrString(child, "name")) != "")
			{
				Bitmap* b = new Bitmap(objName, getOscRootAddress());
				b->loadXml(child);
				addObject(b);
				
				LOG_DEBUG << "Scene \"" << _name << "\": Loaded bitmap \"" << objName << "\" \""
						  << b->getOscRootAddress() << "\"" << std::endl;
			}
			else
			{
				LOG_WARN << "Scene \"" << _name << "\": cannot load bitmap without name, line "
						 << child->Row() << endl;
			}
		}

		else if(child->ValueStr() == "sprite")
		{
			if((objName = Xml::getAttrString(child, "name")) != "")
			{
				Sprite* s = new Sprite(objName, getOscRootAddress());
				s->loadXml(child);
				addObject(s);
				
				LOG_DEBUG << "Scene \"" << _name << "\": Loaded sprite \"" << objName << "\" \""
						  << s->getOscRootAddress() << "\"" << std::endl;
			}
			else
			{
				LOG_WARN << "Scene \"" << _name << "\": cannot load sprite without name, line "
						 << child->Row() << endl;
			}
		}
		
		else if(child->ValueStr() == "image")
		{
			if((objName = Xml::getAttrString(child, "name")) != "")
			{
				Image* i = new Image(objName, getOscRootAddress());
				i->loadXml(child);
				addObject(i);
				
				LOG_DEBUG << "Scene \"" << _name << "\": Loaded image \"" << objName << "\" \""
						  << i->getOscRootAddress() << "\"" << std::endl;
			}
			else
			{
				LOG_WARN << "Scene \"" << _name << "\": cannot load image without name, line "
						 << child->Row() << endl;
			}
		}
		
		else if(child->ValueStr() == "text")
		{
			if((objName = Xml::getAttrString(child, "name")) != "")
			{
				Text* t = new Text(objName, getOscRootAddress());
				t->loadXml(child);
				addObject(t);
				
				LOG_DEBUG << "Scene \"" << _name << "\": Loaded text \"" << objName << "\" \""
						  << t->getOscRootAddress() << "\"" << std::endl;
			}
			else
			{
				LOG_WARN << "Scene \"" << _name << "\": cannot load text without name, line "
						 << child->Row() << endl;
			}
		}

		else if(child->ValueStr() != "background")
		{
			LOG_WARN << "Scene \"" << _name << "\": ignoring unknown element \""
					 << child->ValueStr() << "\"" << endl;
		}


		child = child->NextSiblingElement();
	}

	return true;
}
Beispiel #8
0
Application* XmlAppLoader::parsXml(const char* szFile)
{
    app.clear();

    ErrorLogger* logger  = ErrorLogger::Instance();

    TiXmlDocument doc(szFile);
    if(!doc.LoadFile())
    {
        OSTRINGSTREAM err;
        err<<"Syntax error while loading "<<szFile<<" at line "\
           <<doc.ErrorRow()<<": ";
        err<<doc.ErrorDesc();
        logger->addError(err);
        return NULL;
    }

    /* retrieving root element */
    TiXmlElement *root = doc.RootElement();
    if(!root)
    {
        OSTRINGSTREAM err;
        err<<"Syntax error while loading "<<szFile<<" . ";
        err<<"No root element.";
        logger->addError(err);
        return NULL;
    }

    if(!compareString(root->Value(), "application"))
    {
        //OSTRINGSTREAM err;
        //err<<"File "<<szFile<<" has no tag <application>.";
        //logger->addError(err);
        return NULL;
    }

    /* retrieving name */
    TiXmlElement* name = (TiXmlElement*) root->FirstChild("name");
    if(!name || !name->GetText())
    {
        OSTRINGSTREAM err;
        err<<"Module from "<<szFile<<" has no name.";
        logger->addError(err);
        //return NULL;
    }

    app.setXmlFile(szFile);

    if(name)
    {
        string strname = name->GetText();
        for(unsigned int i=0; i<strname.size(); i++)
            if(strname[i] == ' ')
                strname[i] = '_';
        app.setName(strname.c_str());
    }

    /* retrieving description */
    TiXmlElement* desc;
    if((desc = (TiXmlElement*) root->FirstChild("description")))
        app.setDescription(desc->GetText());

    /* retrieving version */
    TiXmlElement* ver;
    if((ver = (TiXmlElement*) root->FirstChild("version")))
        app.setVersion(ver->GetText());

    /*
     * TODO: setting prefix of the main application is inactivated.
     * Check this should be supported in future or not!
     */
    /*
    //retrieving application prefix
    TiXmlElement* pref;
    if((pref = (TiXmlElement*) root->FirstChild("prefix")))
        app.setPrefix(pref->GetText());
    */

    /* retrieving authors information*/
    TiXmlElement* authors;
    if((authors = (TiXmlElement*) root->FirstChild("authors")))
        for(TiXmlElement* ath = authors->FirstChildElement(); ath;
                ath = ath->NextSiblingElement())
        {
            if(compareString(ath->Value(), "author"))
            {
                Author author;
                if(ath->GetText())
                    author.setName(ath->GetText());
                if(ath->Attribute("email"))
                    author.setEmail(ath->Attribute("email"));
                app.addAuthor(author);
            }
            else
            {
                OSTRINGSTREAM war;
                war<<"Unrecognized tag from "<<szFile<<" at line "\
                   <<ath->Row()<<".";
                logger->addWarning(war);
            }
        }

    /* retrieving resources information*/
    TiXmlElement* resources;
    if((resources = (TiXmlElement*) root->FirstChild("dependencies")))
        for(TiXmlElement* res = resources->FirstChildElement(); res;
                res = res->NextSiblingElement())
        {
            if(compareString(res->Value(), "port"))
            {
                if(res->GetText())
                {
                    ResYarpPort resource(res->GetText());
                    resource.setPort(res->GetText());
                    app.addResource(resource);
                }
            }
            else
            {
                OSTRINGSTREAM war;
                war<<"Unrecognized tag from "<<szFile<<" at line "\
                   <<res->Row()<<".";
                logger->addWarning(war);
            }
        }

    /* retrieving modules information*/
    for(TiXmlElement* mod = root->FirstChildElement(); mod;
            mod = mod->NextSiblingElement())
    {
        if(compareString(mod->Value(), "module"))
        {
            TiXmlElement* element;
            if((element = (TiXmlElement*) mod->FirstChild("name")))
            {
                ModuleInterface module(element->GetText());
                if((element = (TiXmlElement*) mod->FirstChild("node")))
                    module.setHost(element->GetText());

                if((element = (TiXmlElement*) mod->FirstChild("parameters")))
                    module.setParam(element->GetText());

                if((element = (TiXmlElement*) mod->FirstChild("stdio")))
                    module.setStdio(element->GetText());

                if((element = (TiXmlElement*) mod->FirstChild("workdir")))
                    module.setWorkDir(element->GetText());

                if((element = (TiXmlElement*) mod->FirstChild("deployer")))
                    module.setBroker(element->GetText());
                if((element = (TiXmlElement*) mod->FirstChild("prefix")))
                    module.setPrefix(element->GetText());

                if((element = (TiXmlElement*) mod->FirstChild("rank")))
                    module.setRank(atoi(element->GetText()));

#ifdef WITH_GEOMETRY
                element = (TiXmlElement*) mod->FirstChild("geometry");
                if(element && element->GetText())
                {
                    yarp::os::Property prop(element->GetText());
                    GraphicModel model;
                    GyPoint pt;
                    if(prop.check("Pos"))
                    {
                        pt.x = prop.findGroup("Pos").find("x").asDouble();
                        pt.y = prop.findGroup("Pos").find("y").asDouble();
                        model.points.push_back(pt);
                        module.setModelBase(model);
                    }
                }
#endif
                /* retrieving resources information*/
                TiXmlElement* resources;
                if((resources = (TiXmlElement*) mod->FirstChild("dependencies")))
                {
                    for(TiXmlElement* res = resources->FirstChildElement(); res;
                            res = res->NextSiblingElement())
                    {
                        if(compareString(res->Value(), "port"))
                        {
                            if(res->GetText())
                            {
                                ResYarpPort resource(res->GetText());
                                resource.setPort(res->GetText());
                                if(res->Attribute("timeout"))
                                    resource.setTimeout(atof(res->Attribute("timeout")));
                                if(res->Attribute("request"))
                                    resource.setRequest(res->Attribute("request"));
                                if(res->Attribute("reply"))
                                    resource.setReply(res->Attribute("reply"));
                                module.addResource(resource);
                            }
                        }
                        else
                        {
                            OSTRINGSTREAM war;
                            war<<"Unrecognized tag from "<<szFile<<" at line "\
                               <<res->Row()<<".";
                            logger->addWarning(war);
                        }
                    }
                }
                /* retrieving portmaps */
                for(TiXmlElement* map = mod->FirstChildElement(); map;
                            map = map->NextSiblingElement())
                    if(compareString(map->Value(), "portmap"))
                    {
                        TiXmlElement* first;
                        TiXmlElement* second;
                        if((first=(TiXmlElement*) map->FirstChild("old")) &&
                           (second=(TiXmlElement*) map->FirstChild("new")) )
                        {
                            Portmap portmap(first->GetText(), second->GetText());
                            module.addPortmap(portmap);
                        }
                    }

                app.addImodule(module);
            }
            else
            {
                OSTRINGSTREAM war;
                war<<"Module from "<<szFile<<" at line "\
                   <<mod->Row()<<" has not name tag.";
                logger->addWarning(war);
            }

        }
    }

    /* retrieving embedded application information*/
    for(TiXmlElement* embApp = root->FirstChildElement(); embApp;
            embApp = embApp->NextSiblingElement())
    {
        if(compareString(embApp->Value(), "application"))
        {
            TiXmlElement* name;
            TiXmlElement* prefix;
            if((name=(TiXmlElement*) embApp->FirstChild("name")))
            {
                ApplicationInterface IApp(name->GetText());
                if((prefix=(TiXmlElement*) embApp->FirstChild("prefix")))
                    IApp.setPrefix(prefix->GetText());
#ifdef WITH_GEOMETRY
                TiXmlElement* element = (TiXmlElement*) embApp->FirstChild("geometry");
                if(element && element->GetText())
                {
                    yarp::os::Property prop(element->GetText());
                    GraphicModel model;
                    GyPoint pt;
                    if(prop.check("Pos"))
                    {
                        pt.x = prop.findGroup("Pos").find("x").asDouble();
                        pt.y = prop.findGroup("Pos").find("y").asDouble();
                        model.points.push_back(pt);
                        IApp.setModelBase(model);
                    }
                }
#endif
                app.addIapplication(IApp);
            }
            else
            {
                OSTRINGSTREAM war;
                war<<"Incomplete application tag from "<<szFile<<" at line "\
                   <<embApp->Row()<<". (no name)";
                logger->addWarning(war);
            }
        }
    }


    /* retrieving arbitrator information*/
    for(TiXmlElement* arb = root->FirstChildElement(); arb;
            arb = arb->NextSiblingElement())
    {
        if(compareString(arb->Value(), "arbitrator"))
        {
            TiXmlElement* port = (TiXmlElement*) arb->FirstChild("port");
            if(port && port->GetText())
            {
                Arbitrator arbitrator(port->GetText());

                // retrieving rules
                for(TiXmlElement* rule = arb->FirstChildElement(); rule;
                    rule = rule->NextSiblingElement())
                {
                    if(compareString(rule->Value(), "rule"))
                    {
                        if(rule->Attribute("connection"))
                            arbitrator.addRule(rule->Attribute("connection"), rule->GetText());
                    }
                }
#ifdef WITH_GEOMETRY
                TiXmlElement* geometry = (TiXmlElement*) arb->FirstChild("geometry");
                if(geometry && geometry->GetText())
                {
                    yarp::os::Property prop(geometry->GetText());
                    GraphicModel model;
                    if(prop.check("Pos"))
                    {
                        yarp::os::Bottle pos = prop.findGroup("Pos");
                        for(int i=1; i<pos.size(); i++)
                        {
                            GyPoint pt;
                            pt.x = pos.get(i).find("x").asDouble();
                            pt.y = pos.get(i).find("y").asDouble();
                            model.points.push_back(pt);
                        }
                        arbitrator.setModelBase(model);
                    }
                }
#endif
                app.addArbitrator(arbitrator);
            }
            else
            {
                OSTRINGSTREAM war;
                war<<"Incomplete arbitrator tag from "<<szFile<<" at line "\
                   <<arb->Row()<<".";
                logger->addWarning(war);
            }
        }
    }

    /* retrieving connections information*/
    for(TiXmlElement* cnn = root->FirstChildElement(); cnn;
            cnn = cnn->NextSiblingElement())
    {
        if(compareString(cnn->Value(), "connection"))
        {
            TiXmlElement* from = (TiXmlElement*) cnn->FirstChild("from");
            TiXmlElement* to = (TiXmlElement*) cnn->FirstChild("to");

            if(!from)
                from = (TiXmlElement*) cnn->FirstChild("output");
            if(!to)
                to = (TiXmlElement*) cnn->FirstChild("input");

            TiXmlElement* protocol;
            if(from && to)
            {
                string strCarrier;
                if((protocol=(TiXmlElement*) cnn->FirstChild("protocol")) &&
                    protocol->GetText())
                    strCarrier = protocol->GetText();
                Connection connection(from->GetText(),
                                    to->GetText(),
                                    strCarrier.c_str());
                if(from->Attribute("external") &&
                    compareString(from->Attribute("external"), "true"))
                {
                    connection.setFromExternal(true);
                    if(from->GetText())
                    {
                        ResYarpPort resource(from->GetText());
                        resource.setPort(from->GetText());
                        app.addResource(resource);
                    }
                }
                if(to->Attribute("external") &&
                    compareString(to->Attribute("external"), "true"))
                {
                    if(to->GetText())
                    {
                        connection.setToExternal(true);
                        ResYarpPort resource(to->GetText());
                        resource.setPort(to->GetText());
                        app.addResource(resource);
                    }
                }

                //Connections which have the same port name in Port Resources
                // should also be set as external
                for(int i=0; i<app.resourcesCount(); i++)
                {
                    ResYarpPort res = app.getResourceAt(i);
                    if(compareString(res.getPort(), connection.from()))
                        connection.setFromExternal(true);
                    if(compareString(res.getPort(), connection.to()))
                        connection.setToExternal(true);
                }

                if(cnn->Attribute("id"))
                    connection.setId(cnn->Attribute("id"));

                if(cnn->Attribute("persist") &&
                        compareString(cnn->Attribute("persist"), "true"))
                    connection.setPersistent(true);

#ifdef WITH_GEOMETRY
                TiXmlElement* geometry = (TiXmlElement*) cnn->FirstChild("geometry");
                if(geometry && geometry->GetText())
                {
                    yarp::os::Property prop(geometry->GetText());
                    GraphicModel model;
                    if(prop.check("Pos"))
                    {
                        yarp::os::Bottle pos = prop.findGroup("Pos");
                        for(int i=1; i<pos.size(); i++)
                        {
                            GyPoint pt;
                            pt.x = pos.get(i).find("x").asDouble();
                            pt.y = pos.get(i).find("y").asDouble();
                            model.points.push_back(pt);
                        }
                        connection.setModelBase(model);
                    }
                }
#endif

                app.addConnection(connection);
            }
            else
            {
                OSTRINGSTREAM war;
                war<<"Incomplete connection tag from "<<szFile<<" at line "\
                   <<cnn->Row()<<".";
                logger->addWarning(war);
            }
        }
    }


    return &app;

}
Beispiel #9
0
		bool SimXMLLoader::parseAgentProfile( TiXmlElement * node, AgentInitializer * agentInit ) {
			// Extract the name
			const char * nameCStr = node->Attribute( "name" );
			if ( nameCStr == 0x0 ) {
				logger << Logger::ERR_MSG << "The AgentProfile defined on line " << node->Row() << " is missing the required \"name\" attribute.";
				return false;
			}
			std::string name( nameCStr );
			if ( _profiles.find( name ) != _profiles.end() ) {
				logger << Logger::ERR_MSG << "The AgentProfile defined on line " << node->Row() << " has a name value (\"" << name << "\")that has previously been used.";
				return false;
			}

			AgentInitializer * init;
			// test inheritance
			const char * parentCStr = node->Attribute( "inherits" );
			if ( parentCStr ) {
				std::string pName( parentCStr );
				HASH_MAP< std::string, AgentInitializer * >::iterator itr = _profiles.find( pName );
				if ( itr == _profiles.end() ) {
					logger << Logger::ERR_MSG << "The AgentProfile on line " << node->Row() << " inherits from the undefined AgentProfile \"" << pName << "\".  Make sure the parent profile is defined <i>before</i> the child profile.";
					return false;
				} else {
					init = itr->second->copy();
				}
			} else {
				init = agentInit->copy();
				init->setDefaults();
			}
			_profiles[ name ] = init;

			for( TiXmlElement * child = node->FirstChildElement(); child; child = child->NextSiblingElement()) {
				if ( ! init->parseProperties( child, _sceneFldr) ) {
					logger << Logger::ERR_MSG << "Error parsing AgentProfile properties from line " << child->Row() << ".";
					return false;
				}
			}
			return true;
		}
Beispiel #10
0
		bool SimXMLLoader::parseAgentGroup( TiXmlElement * node, AgentInitializer * agentInit ) {
			// 2-pass approach
			// Pass 1 get the profile selector
			// Pass 2 initialize AgentGenerator (Generator for short)

			// Get the profile selector - 
			TiXmlElement* child;
			ProfileSelector * profileSel = 0x0;
			StateSelector * stateSel = 0x0;
			// First pass, skip Agents
			for( child = node->FirstChildElement(); child; child = child->NextSiblingElement()) {
				if ( child->ValueStr() == "ProfileSelector" ) {
					if ( profileSel != 0x0 ) {
						// There should be only one.  If there are multiple, only the first will have an effect.
						logger << Logger::WARN_MSG << "Found multiple ProfileSelector tags in the AgentGroup on line " << node->Row() << ".  Only the first will be used.";
						continue;
					}
					profileSel = ProfileSelectorDB::getInstance( child, _sceneFldr );
					if ( profileSel == 0x0 ) {
						logger << Logger::ERR_MSG << "Unable to instantiate the profile selector specification line " << child->Row() << ".";
						return false;
					}
					if ( ! profileSel->cacheProfiles( _profiles ) ) {
						logger << Logger::ERR_MSG << "ProfileSelector on line " << child->Row() << " was unable to find a named profile.";
						return false;
					}
				} else if ( child->ValueStr() == "StateSelector" ) {
					if ( stateSel != 0x0 ) {
						// There should be only one.  If there are multiple, only the first will have an effect.
						logger << Logger::WARN_MSG << "Found multiple StateSelector tags in the AgentGroup on line " << node->Row() << ".  Only the first will be used.";
						continue;
					}
					stateSel = StateSelectorDB::getInstance( child, _sceneFldr );
					if ( stateSel == 0x0 ) {
						logger << Logger::ERR_MSG << "Unable to instantiate the state selector specification line " << child->Row() << ".";
						return false;
					}
				}
			}
			if ( profileSel == 0x0 ) {
				logger << Logger::ERR_MSG << "No profile selector defined for the AgentGroup on line " << node->Row() << ".";
				return false;
			}
			if ( stateSel == 0x0 ) {
				logger << Logger::ERR_MSG << "No state selector defined for the AgentGroup on line " << node->Row() << ".";
				return false;
			}

			// Second pass, parse Generators
			for( child = node->FirstChildElement(); child; child = child->NextSiblingElement()) {
				if ( child->ValueStr() == "Generator" ) {
					AgentGenerator * generator = AgentGeneratorDB::getInstance( child, _sceneFldr );

					if ( generator == 0x0 ) {
						logger << Logger::ERR_MSG << "Unable to instantiate agent generator specifcation on line " << child->Row() << ".";
						return false;
					}
					// Now instantiate the agents
					const size_t AGT_COUNT = generator->agentCount();
					for ( size_t i = 0; i < AGT_COUNT; ++i ) {
						Vector2 p = generator->agentPos( i );
						BaseAgent * agent = _sim->addAgent( p, profileSel->getProfile() );
						_sim->getInitialState()->setAgentState( agent->_id, stateSel->getState() );
					}
					_agtCount += (unsigned int) AGT_COUNT;

					generator->destroy();
				}
			}
			
			return true;
		}
Beispiel #11
0
bool FSMDescrip::loadFromXML(const std::string& xmlName, bool verbose) {
  logger << Logger::INFO_MSG << "Loading behavior from xml: " << xmlName;
  TiXmlDocument xml(xmlName);
  bool loadOkay = xml.LoadFile();

  if (!loadOkay) {
    logger << Logger::ERR_MSG << "Could not load behavior configuration xml (";
    logger << xmlName << ") due to xml syntax errors.\n";
    logger << "\t" << xml.ErrorDesc();
    return false;
  }

  TiXmlElement* popNode = xml.RootElement();
  if (!popNode) {
    logger << Logger::ERR_MSG << "Root element does not exist.";
    return false;
  }
  if (popNode->ValueStr() != "BFSM") {
    logger << Logger::ERR_MSG << "Root element value should be \"BFSM\".";
    return false;
  }

  std::string absPath;
  os::path::absPath(xmlName, absPath);
  std::string junk;
  os::path::split(absPath, _behaviorFldr, junk);
  logger << Logger::INFO_MSG << "Behavior root: " << _behaviorFldr;

  TiXmlElement* child;
  for (child = popNode->FirstChildElement(); child; child = child->NextSiblingElement()) {
    if (child->ValueStr() == "GoalSet") {
      int i;
      if (!child->Attribute("id", &i)) {
        logger << Logger::ERR_MSG << "GoalSet requires an \"id\" property.";
        return false;
      }
      size_t setID = static_cast<size_t>(i);
      // confirm that the id doesn't already exist
      if (_goalSets.find(setID) != _goalSets.end()) {
        logger << Logger::WARN_MSG << "Found multiple GoalSets with the same id: ";
        logger << setID << ".\n\tGoal definitions will be merged!";
      } else {
        _goalSets[setID] = new GoalSet();
      }
      TiXmlElement* goalNode;
      for (goalNode = child->FirstChildElement(); goalNode;
           goalNode = goalNode->NextSiblingElement()) {
        if (goalNode->ValueStr() == "Goal") {
          Goal* goal = parseGoal(goalNode, _behaviorFldr);
          if (goal == 0x0) {
            logger << Logger::ERR_MSG << "Error parsing a goal description.";
            return false;
          }
          // Make sure that this goal doesn't duplicate previous goal ids
          if (!_goalSets[setID]->addGoal(goal->getID(), goal)) {
            logger << Logger::ERR_MSG << "GoalSet " << setID;
            logger << " has two goals with the identifier: " << goal->getID();
            logger << " (second appears on line " << goalNode->Row() << ").";
            return false;
          }
        } else {
          logger << Logger::WARN_MSG
                 << "Found a child tag of the GoalSet that "
                    "is not a \"Goal\" tag on line "
                 << goalNode->Row()
                 << ". "
                    "It will be ignored.";
        }
      }

    } else if (child->ValueStr() == "State") {
      if (!parseState(child, _behaviorFldr, _states)) {
        return false;
      }
    } else if (child->ValueStr() == "Transition") {
      std::string from;
      Transition* trans = parseTransition(child, _behaviorFldr, from);
      if (trans == 0x0) {
        return false;
      }

      addTransition(from, trans);
    } else if (child->ValueStr() == "VelModifier") {
      VelModifier* vel = parseVelModifier(child, _behaviorFldr);
      if (vel == 0x0) {
        return false;
      } else {
        _velModifiers.push_back(vel);
      }
    } else if (child->ValueStr() == "Task") {
      Task* task = parseTask(child, _behaviorFldr);
      if (task == 0x0) {
        logger << Logger::WARN_MSG << "User-specified Task on line ";
        logger << child->Row()
               << " couldn't be instantiated.  "
                  "It is being ignored.";
      } else {
        _tasks.push_back(task);
      }
    } else if (child->ValueStr() == "EventSystem") {
      if (!EVENT_SYSTEM->parseEvents(child, _behaviorFldr)) {
        return false;
      }
    } else {
      logger << Logger::ERR_MSG << "Unrecognized tag as child of <Population>: <";
      logger << child->ValueStr() << ">.";
      return false;
    }
  }

  return true;
}
bool XmlResLoader::parsXml(const char* szFile)
{
    computers.clear();

    ErrorLogger* logger  = ErrorLogger::Instance();
    
    TiXmlDocument doc(szFile);
    if(!doc.LoadFile()) 
    {
        OSTRINGSTREAM err;
        err<<"Syntax error while loading "<<szFile<<" at line "\
           <<doc.ErrorRow()<<": ";
        err<<doc.ErrorDesc();
        logger->addError(err);
        return false;
    }
    /* retrieving root module */
    TiXmlElement *root = doc.RootElement();
    if(!root)
    {
        OSTRINGSTREAM err;
        err<<"Syntax error while loading "<<szFile<<" . ";
        err<<"No root element.";
        logger->addError(err);
        return false;
    }
        
    if(!compareString(root->Value(), "resources"))
    {
        /*
        OSTRINGSTREAM msg;
        msg<<szFile<<" is not a resource descriptor file.";
        logger->addWarning(msg);
        */
        return false;
    }
    
    /* retrieving all computers descriptions */
    for(TiXmlElement* restag = root->FirstChildElement();
            restag; restag = restag->NextSiblingElement())
    {
        /* retrieving a computer resource */    
        if(compareString(restag->Value(), "computer"))
        {
            Computer computer;
            computer.setXmlFile(szFile);

            for(TiXmlElement* comptag = restag->FirstChildElement();
                comptag; comptag = comptag->NextSiblingElement())
            {       
                 /* retrieving name */
                if(compareString(comptag->Value(), "name"))                               
                    computer.setName(comptag->GetText());

                /* retrieving description */
                 if(compareString(comptag->Value(), "description"))                  
                    computer.setDescription(comptag->GetText());

                /* retrieving disablility */
                if(compareString(comptag->Value(), "disable"))
                {
                    if(compareString(comptag->GetText(), "yes"))
                        computer.setDisable(true);
                }

                // platform
                if(compareString(comptag->Value(), "platform"))
                {
                    Platform os;
                    TiXmlElement* element;
                    if((element = (TiXmlElement*) comptag->FirstChild("name")))
                        os.setName(element->GetText());
                    else
                    {
                        OSTRINGSTREAM war;
                        war<<"Platform from "<<szFile<<" at line "\
                           <<comptag->Row()<<" has no name.";
                        logger->addWarning(war);                
                    }
                    
                    if((element = (TiXmlElement*) comptag->FirstChild("distribution")))
                        os.setDistribution(element->GetText());
                    
                    if((element = (TiXmlElement*) comptag->FirstChild("release")))
                        os.setRelease(element->GetText()); 

                    computer.setPlatform(os);
                } // end of platform tag

                // memory
                if(compareString(comptag->Value(), "memory"))
                {
                    Memory mem;
                    TiXmlElement* element;
                    if((element = (TiXmlElement*) comptag->FirstChild("total_space")))
                        mem.setTotalSpace((Capacity)atol(element->GetText()));               
                   computer.setMemory(mem);
                } // end of memory tag

                // storage
                if(compareString(comptag->Value(), "storage"))
                {
                    Storage stg;
                    TiXmlElement* element;
                    if((element = (TiXmlElement*) comptag->FirstChild("total_space")))
                        stg.setTotalSpace((Capacity)atol(element->GetText()));               
                   computer.setStorage(stg);
                } // end of storage tag

                // processor
                if(compareString(comptag->Value(), "processor"))
                {
                    Processor proc;
                    TiXmlElement* element;
                    if((element = (TiXmlElement*) comptag->FirstChild("architecture")))
                        proc.setArchitecture(element->GetText());
                    if((element = (TiXmlElement*) comptag->FirstChild("model")))
                        proc.setModel(element->GetText());
                    if((element = (TiXmlElement*) comptag->FirstChild("cores")))
                        proc.setCores((size_t)atoi(element->GetText()));               
                    if((element = (TiXmlElement*) comptag->FirstChild("frequency")))
                        proc.setFrequency(atof(element->GetText()));
                   computer.setProcessor(proc);
                } // end of processor tag

                // network
                if(compareString(comptag->Value(), "network"))
                {
                    Network net;
                    TiXmlElement* element;
                    if((element = (TiXmlElement*) comptag->FirstChild("ip4")))
                        net.setIP4(element->GetText());
                    if((element = (TiXmlElement*) comptag->FirstChild("ip6")))
                        net.setIP6(element->GetText());
                    if((element = (TiXmlElement*) comptag->FirstChild("mac")))
                        net.setMAC(element->GetText());
                    computer.setNetwork(net);
                } // end of network tag


                // gpu
                if(compareString(comptag->Value(), "gpu"))
                {
                    GPU gpu;
                    TiXmlElement* element;
                    if((element = (TiXmlElement*) comptag->FirstChild("name")))
                        gpu.setName(element->GetText());
                    if((element = (TiXmlElement*) comptag->FirstChild("capability")))
                        gpu.setCompCompatibility(element->GetText());
                    if((element = (TiXmlElement*) comptag->FirstChild("cores")))
                        gpu.setCores((size_t)atoi(element->GetText()));
                    if((element = (TiXmlElement*) comptag->FirstChild("frequency")))
                        gpu.setFrequency(atof(element->GetText()));
                    if((element = (TiXmlElement*) comptag->FirstChild("register_block")))
                        gpu.setResgisterPerBlock((size_t)atoi(element->GetText()));
                    if((element = (TiXmlElement*) comptag->FirstChild("thread_block")))
                        gpu.setThreadPerBlock((size_t)atoi(element->GetText()));
                    if((element = (TiXmlElement*) comptag->FirstChild("overlap")))
                    {
                        if(compareString(element->GetText(), "yes"))
                            gpu.setOverlap(true);
                        else
                            gpu.setOverlap(false);
                    }
                 
                    // global memory
                    if(comptag->FirstChild("global_memory"))
                    {
                        TiXmlElement* element;
                        element = (TiXmlElement*) comptag->FirstChild("global_memory");
                        if((element = (TiXmlElement*) element->FirstChild("total_space")))
                            gpu.setGlobalMemory((Capacity)atol(element->GetText()));            
                    } // end of global memory tag

                    // shared memory
                    if(comptag->FirstChild("shared_memory"))
                    {
                        TiXmlElement* element;
                        element = (TiXmlElement*) comptag->FirstChild("shared_memory");
                        if((element = (TiXmlElement*) element->FirstChild("total_space")))
                            gpu.setSharedMemory((Capacity)atol(element->GetText()));            
                    } // end of shared memory tag

                    // constant memory
                    if(comptag->FirstChild("constant_memory"))
                    {
                        TiXmlElement* element;
                        element = (TiXmlElement*) comptag->FirstChild("constant_memory");
                        if((element = (TiXmlElement*) element->FirstChild("total_space")))
                            gpu.setConstantMemory((Capacity)atol(element->GetText()));            
                    } // end of shared memory tag

                   computer.addPeripheral(gpu);
                } // end of gpu tag
            } // end of computer loop 

            computers.push_back(computer);
        } // end of if computer
    } // end of resources 
    return true;
}
Beispiel #13
0
Island::Island(const std::string& filename, int pos_x, int pos_y, std::vector<bool>& waterTiles) : m_x(pos_x), m_y(pos_y), m_tiles(NULL), m_defaultTile(0)
{
	m_defaultTile = Tile::getDefaultTile();
	std::cout << "Trying to load island \"" << filename << "\"" << std::endl;
	TiXmlDocument document;
	if (!document.PHYSFS_LoadFile(filename))
	{
		throw FileLoadException(filename, document.ErrorDesc());
	}

	if(!document.RootElement() || document.RootElement()->ValueStr() != "island")
		throw XMLException(filename, -1, "This is no valid island XML file (missing island root element)");

	TiXmlElement *island = document.RootElement();
	if (!island->Attribute("cols"))
		throw XMLException(filename, island->Row(), "Missing attribute cols");
	if (!island->Attribute("rows"))
		throw XMLException(filename, island->Row(), "Missing attribute rows");
	if (!island->Attribute("clime"))
		throw XMLException(filename, island->Row(), "Missing attribute clime");
	std::stringstream attr;
	attr << island->Attribute("cols") << " " << island->Attribute("rows");
	attr >> m_cols >> m_rows;
	m_clime = island->Attribute("clime");
	std::cout << "Creating " << (m_rows * m_cols) << " tiles" << std::endl;
	m_tiles = new Tile* [m_rows * m_cols];
	memset(m_tiles, 0, sizeof(Tile*) * m_rows * m_cols);

	TiXmlElement *terrain = island->FirstChildElement("terrain");
	if (!terrain)
		throw XMLException(filename, island->Row(), "Missing toplevel element terrain");

	TiXmlElement *row = terrain->FirstChildElement("row");
	if (!terrain)
		throw XMLException(filename, terrain->Row(), "Missing row subelements");
	while (row)
	{
		if (!row->Attribute("value"))
			throw XMLException(filename, row->Row(), "Missing attribute value");
		std::stringstream rowStr(row->Attribute("value"));
		int rowInt;
		rowStr >> rowInt;
		rowInt--;
		TiXmlElement *col = row->FirstChildElement("col");
		if (!col)
			throw XMLException(filename, row->Row(), "Missing col subelements");
		while (col)
		{
			if (!col->Attribute("value"))
				throw XMLException(filename, col->Row(), "Missing attribute value");
			std::stringstream colStr(col->Attribute("value"));
			int colInt;
			colStr >> colInt;
			colInt--;

			TiXmlElement *tile = col->FirstChildElement("tile");
			if (!tile)
				throw XMLException(filename, col->Row(), "Missing tile subelement");
			if (((rowInt * m_cols) + colInt) >= m_cols * m_rows)
				std::cout << "WARNING! Index out of bounds. Row: " << rowInt << ", column: " << colInt << std::endl;
			else
			{
				m_tiles[(rowInt * m_cols) + colInt] = new Tile(tile);
				if (m_tiles[(rowInt * m_cols) + colInt] == NULL) {
					std::cout << "TILE CREATION FAILED" << std::endl;
				}
				waterTiles[(rowInt * m_cols) + colInt] = false;
			}

			col = col->NextSiblingElement("col");
		}
		row = row->NextSiblingElement("row");
	}

	std::cout << "Succesfully loaded island \"" << filename << "\"" << std::endl;
	std::cout << "\tColums: " << m_cols << std::endl;
	std::cout << "\tRows: " << m_rows << std::endl;
/*	std::cout << "debug-listing 0,0 to 9,9" << std::endl;
	for (int y = 0; y < 10; y++)
	{
		for (int x = 0; x < 10; x++)
		{
			std::cout << m_tiles[(y * m_cols) + x]->getName();
			std::cout << ",";
		}
		std::cout << std::endl;
	}*/
}
Beispiel #14
0
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 &amp; 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 )
	QueryPerformanceCounter( (LARGE_INTEGER*) (&start) );
	#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" );
	doc.Print( stdout );

	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 Dinosours!" 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();
	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 sytax.
	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 = '&gt;' />" );
		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 doc;
		doc.Parse( error );
		XmlTest( "Error row", doc.ErrorRow(), 3 );
		XmlTest( "Error column", doc.ErrorCol(), 17 );
		//printf( "error=%d id='%s' row %d col%d\n", (int) doc.Error(), doc.ErrorDesc(), doc.ErrorRow()+1, doc.ErrorCol() + 1 );

	}
	{
		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 );
	}
	{
		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 = "<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 );
	}

#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

	// --------------------------------------------------------
	// 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 comletely 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.", 0, (int) 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

	//////////////////////////////////////////////////////
	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
			// verifing 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 &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
				" It also has &lt;, &gt;, and &amp;, as well as a fake copyright &#xA9;.\"> </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 &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
					 " It also has &lt;, &gt;, and &amp;, 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&#xA;</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 );

			//doc.Print( stdout, 0 );

            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

	#if defined( WIN32 ) && defined( TUNE )
	QueryPerformanceCounter( (LARGE_INTEGER*) (&end) );
	QueryPerformanceFrequency( (LARGE_INTEGER*) (&freq) );
	printf( "Time for run: %f\n", ( double )( end-start ) / (double) freq );
	#endif

	printf ("\nPass %d, Fail %d\n", gPass, gFail);
	return gFail;
}
Beispiel #15
0
		bool SimXMLLoader::loadFromXML( const std::string & filename, AgentInitializer * agentInit, bool verbose ) {
			// COnfirms file is
			//	a) available for reading
			//	b) valid xml
			//	c) An "Experiment"
			if ( verbose ) logger << Logger::INFO_MSG << "Loading from xml: " << filename << ".";
			TiXmlDocument xml( filename );
			bool loadOkay = xml.LoadFile();

			if ( !loadOkay ) {	// load xml file
				logger << Logger::ERR_MSG << "Could not load simulation configuration xml (" << filename << ") due to xml syntax errors.\n";
				logger << "\t" << xml.ErrorDesc();
				return false;
			}

			TiXmlElement* experimentNode = xml.RootElement();	
			if( ! experimentNode ) {
				logger << Logger::ERR_MSG << "Scene configuration (" << filename << ") does not contain a root element.";
				return false;
			}

			if( experimentNode->ValueStr () != "Experiment" ) {
				logger << Logger::ERR_MSG << "Scene configuration (" << filename << ")'s root element is not \"Experiment\".";
				return false;
			}

			std::string absPath;
			os::path::absPath( filename, absPath );
			std::string junk;
			os::path::split( absPath, _sceneFldr, junk );
			logger << Logger::INFO_MSG << "Scene root: " << _sceneFldr << ".";		

			bool commonDone = false;	// common experiment parameters parsed
			bool targetDone = !_sim->hasExpTarget();	// target experiment parameters parsed
			bool spatialQueryDone = false;	// spatial query must be finished before obstacles and agents can be created

			// Tags I'm not ready to parse - only parse agent sets and obstacles AFTER experiment
			//	parameters
			std::list< TiXmlElement * > tagQueue;
			
			TiXmlElement* child;
			for( child = experimentNode->FirstChildElement(); child; child = child->NextSiblingElement()) {
				if ( child->ValueStr() == "Common" ) {
					// Currently the only "common" experiment parameter is the time step
					TiXmlAttribute * attr;
					for ( attr = child->FirstAttribute(); attr; attr = attr->Next() ) {
						try {
							if ( !_sim->setExpParam( attr->Name(), attr->ValueStr() ) ) {
								logger << Logger::WARN_MSG << "Unrecognized parameter in the global \"Common\" parameters (" << attr->Name() << ") on line " << child->Row() << "\n";
							}
						} catch ( XMLParamException e ) {
							logger << Logger::ERR_MSG << e.what();
							return false;
						}
					}
					commonDone = true;
				} else if ( child->ValueStr() == "AgentProfile" ) {
					if ( !parseAgentProfile( child, agentInit ) ) {
						return false;
					}
				} else if ( child->ValueStr() == "AgentGroup" ) {
					if ( ! ( commonDone || targetDone || spatialQueryDone ) ) {
						tagQueue.push_back( child );
					} else {
						if ( !parseAgentGroup( child, agentInit ) ) {
							return false;
						}
					}
				} else if ( child->ValueStr() == "ObstacleSet" ) {
					if ( ! ( commonDone || targetDone || spatialQueryDone) ) {
						tagQueue.push_back( child );
					} else {
						if ( ! parseObstacleSet( child ) ) {
							return false;
						}
					}
				} else if ( child->ValueStr() == "Elevation" ) {
					if ( _sim->hasElevation() ) {
						logger << Logger::ERR_MSG << "More than one elevation has been specified.  Found redundant elevation specification on line " << child->Row() << ".";
						return false;
					}
					Elevation * elevation = ElevationDB::getInstance( child, _sceneFldr );
					if ( elevation == 0x0 ) {
						logger << Logger::ERR_MSG << "Unable to instantiate elevation specifcation on line " << child->Row() << ".";
						return false;
					} else {
						_sim->setElevationInstance( elevation );
					}
					Menge::ELEVATION = elevation;
				} else if ( child->ValueStr() == "SpatialQuery" ) {
					if ( _sim->hasSpatialQuery() ) {
						logger << Logger::ERR_MSG << "More than one spatial query implementation has been specified.  Found redundant spatial query specification on line " << child->Row() << ".";
						return false;
					}
					SpatialQuery * spQuery = SpatialQueryDB::getInstance( child, _sceneFldr );
					if ( spQuery == 0x0 ) {
						logger << Logger::ERR_MSG << "Unable to instantiate spatial query specifcation on line " << child->Row() << ".";
						return false;
					} else {
						_sim->setSpatialQuery( spQuery );
						spatialQueryDone = true;
					}
				} else {	// target parameter 
					if ( !targetDone && _sim->isExpTarget( child->ValueStr() ) ) {
						// Parse the target
						TiXmlAttribute * attr;
						for ( attr = child->FirstAttribute(); attr; attr = attr->Next() ) {
							try {
								if ( ! _sim->setExpParam( attr->Name(), attr->ValueStr() ) ) {
									logger << Logger::WARN_MSG << "Unrecognized parameter in the global \"" << child->ValueStr() << "\" parameters (" << attr->Name() << ") on line " << child->Row() << "\n";
								}
							} catch ( XMLParamException e ) {
								logger << Logger::ERR_MSG << e.what() << " (on line " << child->Row() << ")";
								return false;
							}
						}
						targetDone = true;
					}
				} 
			}
			if ( !targetDone || !commonDone || !spatialQueryDone) {
				logger << Logger::ERR_MSG << "Missing required experiment parameters: \n";
				if ( !targetDone ) logger << "\tmodel simulation parameters ";
				if ( !commonDone ) logger << "\tcommon simulation parameters ";
				if ( !spatialQueryDone ) logger << "\tSpatial Query ";
				return false;
			}
			// Now parse any of the tags that were skipped while waiting for experiment configuration
			std::list< TiXmlElement * >::iterator tagItr = tagQueue.begin();
			for ( ; tagItr != tagQueue.end(); ++tagItr ) {
				TiXmlElement * child = *tagItr;
				if ( child->ValueStr() == "AgentGroup" ) {
					if ( !parseAgentGroup( child, agentInit ) ) {
						return false;
					}
				} else if ( child->ValueStr() == "ObstacleSet" ) {
					if ( ! parseObstacleSet( child ) ) {
							return false;
						}
				} else {
					logger << Logger::ERR_MSG << "XML contains an invalid tag: " << child->ValueStr() << " on line " << child->Row() << ".";
					return false;
				}
			}

			if ( _agtCount == 0 ) {
				// TODO: Change this test when agent sources are introduced
				//	in this case, it is possible to start with no agents and then add them
				//	w.r.t. time.
				logger << Logger::ERR_MSG << "No agents defined in simulation.";
				return false;
			}

			// free up the profiles
			//	TODO: I'll need to save these when I have AgentSources.
			for ( HASH_MAP< std::string, AgentInitializer * >::iterator itr = _profiles.begin();
				itr != _profiles.end();
				++itr ) 
			{
				delete itr->second;
			}
			_profiles.clear();

			return _sim->initSpatialQuery();
		}
Beispiel #16
0
Module* XmlModLoader::parsXml(const char* szFile)
{
    module.clear();
    ErrorLogger* logger  = ErrorLogger::Instance();

    TiXmlDocument doc(szFile);
    if(!doc.LoadFile())
    {
        OSTRINGSTREAM err;
        err<<"Syntax error while loading "<<szFile<<" at line "\
           <<doc.ErrorRow()<<": ";
        err<<doc.ErrorDesc();
        logger->addError(err);
        return nullptr;
    }

    /* retrieving root module */
    TiXmlElement *root = doc.RootElement();
    if(!root)
    {
        OSTRINGSTREAM err;
        err<<"Syntax error while loading "<<szFile<<" . ";
        err<<"No root element.";
        logger->addError(err);
        return nullptr;
    }

    if(!compareString(root->Value(), "module"))
    {
        /*
        OSTRINGSTREAM msg;
        msg<<szFile<<" is not a module descriptor file.";
        logger->addWarning(msg);
        */
        return nullptr;
    }

    /* retrieving name */
    auto* name = (TiXmlElement*) root->FirstChild("name");
    if(!name || !name->GetText())
    {
        OSTRINGSTREAM err;
        err<<"Module from "<<szFile<<" has no name.";
        logger->addError(err);
        //return NULL;
    }

    for(TiXmlElement* var = root->FirstChildElement("var"); var; var = var->NextSiblingElement())
    {
        if(var->Attribute("name") && var->GetText())
        {
            parser->addVariable(var->Attribute("name"), var->GetText());
        }
    }

    module.setXmlFile(szFile);

    if(name)
        module.setName(parser->parseText(name->GetText()).c_str());

    /* retrieving description */
    TiXmlElement* desc;
    if((desc = (TiXmlElement*) root->FirstChild("description")))
        module.setDescription(parser->parseText(desc->GetText()).c_str());

    /* retrieving version */
    TiXmlElement* ver;
    if((ver = (TiXmlElement*) root->FirstChild("version")))
        module.setVersion(parser->parseText(ver->GetText()).c_str());


    /* retrieving parameter */
    TiXmlElement* arguments;
    if((arguments = (TiXmlElement*) root->FirstChild("arguments")))
        for(TiXmlElement* param = arguments->FirstChildElement(); param;
                param = param->NextSiblingElement())
        {
            if(compareString(param->Value(), "param"))
            {
                if(param->GetText())
                {
                    bool brequired = false;
                    if(compareString(param->Attribute("required"), "yes"))
                        brequired = true;
                    Argument arg(parser->parseText(param->GetText()).c_str(),
                                 brequired,
                                 param->Attribute("desc"));
                    arg.setDefault(param->Attribute("default"));
                    module.addArgument(arg);
                }
            }
            else
            if(compareString(param->Value(), "switch"))
            {
                if(param->GetText())
                {
                    bool brequired = false;
                    if(compareString(param->Attribute("required"), "yes"))
                        brequired = true;
                    Argument arg(parser->parseText(param->GetText()).c_str(),
                                 brequired,
                                 param->Attribute("desc"), true);
                    arg.setDefault(param->Attribute("default"));
                    module.addArgument(arg);
                }
            }
            else
            {
                OSTRINGSTREAM war;
                war<<"Unrecognized tag from "<<szFile<<" at line "\
                   <<param->Row()<<".";
                logger->addWarning(war);
            }

        }


    /* retrieving rank */
    TiXmlElement* rank;
    if((rank = (TiXmlElement*) root->FirstChild("rank")) &&
        rank->GetText())
        module.setRank(atoi(parser->parseText(rank->GetText()).c_str()));


    /* retrieving authors information*/
    TiXmlElement* authors;
    if((authors = (TiXmlElement*) root->FirstChild("authors")))
        for(TiXmlElement* ath = authors->FirstChildElement(); ath;
                ath = ath->NextSiblingElement())
        {
            if(compareString(ath->Value(), "author"))
            {
                Author author;
                if(ath->GetText())
                    author.setName(parser->parseText(ath->GetText()).c_str());
                if(ath->Attribute("email"))
                    author.setEmail(ath->Attribute("email"));
                module.addAuthor(author);
            }
            else
            {
                OSTRINGSTREAM war;
                war<<"Unrecognized tag from "<<szFile<<" at line "\
                   <<ath->Row()<<".";
                logger->addWarning(war);
            }

        }


   /* retrieving data */
    if(root->FirstChild("data"))
        for(TiXmlElement* data = root->FirstChild("data")->FirstChildElement();
            data; data = data->NextSiblingElement())
        {
            /* output data */
            if(compareString(data->Value(), "output"))
            {
                OutputData output;

                if(compareString(data->Attribute("port_type"), "stream") || !data->Attribute("port_type"))
                    output.setPortType(STREAM_PORT);
                else if(compareString(data->Attribute("port_type"), "event"))
                    output.setPortType(EVENT_PORT);
                else if(compareString(data->Attribute("port_type"), "service"))
                    output.setPortType(SERVICE_PORT);
                else
                {
                    OSTRINGSTREAM war;
                    war<<"Unknown port type \'"<<data->Attribute("port_type")<<"\' from "<<szFile<<" at line "\
                       <<data->Row()<<". Available types : stream, event, service";
                    logger->addWarning(war);
                }


                TiXmlElement* element;
                if(output.getPortType() != SERVICE_PORT )
                {
                    if((element = (TiXmlElement*) data->FirstChild("type")))
                        output.setName(parser->parseText(element->GetText()).c_str());
                    else
                    {
                        OSTRINGSTREAM war;
                        war<<"Output data from "<<szFile<<" at line "\
                           <<data->Row()<<" has no type.";
                        logger->addWarning(war);
                    }
                }
                else
                    output.setName("*");

                if((element = (TiXmlElement*) data->FirstChild("port")))
                {
                    output.setPort(parser->parseText(element->GetText()).c_str());
                    output.setCarrier(element->Attribute("carrier"));
                }
                else
                {
                    OSTRINGSTREAM war;
                    war<<"Output data from "<<szFile<<" at line "\
                       <<data->Row()<<" has no port.";
                    logger->addWarning(war);
                }

                if((element = (TiXmlElement*) data->FirstChild("description")))
                    output.setDescription(parser->parseText(element->GetText()).c_str());

                module.addOutput(output);
            } // end of output data

            /* input data */
            if(compareString(data->Value(), "input"))
            {
                InputData input;

                if(compareString(data->Attribute("port_type"), "stream") || !data->Attribute("port_type"))
                    input.setPortType(STREAM_PORT);
                else if(compareString(data->Attribute("port_type"), "event"))
                    input.setPortType(EVENT_PORT);
                else if(compareString(data->Attribute("port_type"), "service"))
                    input.setPortType(SERVICE_PORT);
                else
                {
                    OSTRINGSTREAM war;
                    war<<"Unknown port type \'"<<data->Attribute("port_type")<<"\' from "<<szFile<<" at line "\
                       <<data->Row()<<". Available types : stream, event, service";
                    logger->addWarning(war);
                }

                TiXmlElement* element;
                if(input.getPortType() != SERVICE_PORT )
                {

                    if((element = (TiXmlElement*) data->FirstChild("type")))
                        input.setName(parser->parseText(element->GetText()).c_str());
                    else
                    {
                        OSTRINGSTREAM war;
                        war<<"Input data from "<<szFile<<" at line "\
                           <<data->Row()<<" has no type.";
                        logger->addWarning(war);
                    }
                }
                else
                    input.setName("rpc");

                if((element = (TiXmlElement*) data->FirstChild("port")))
                {
                    input.setPort(parser->parseText(element->GetText()).c_str());
                    input.setCarrier(element->Attribute("carrier"));
                }
                else
                {
                    OSTRINGSTREAM war;
                    war<<"Input data from "<<szFile<<" at line "\
                       <<data->Row()<<" has no port.";
                    logger->addWarning(war);
                }

                if((element = (TiXmlElement*) data->FirstChild("description")))
                    input.setDescription(parser->parseText(element->GetText()).c_str());

                if((element = (TiXmlElement*) data->FirstChild("required")))
                    if(compareString(parser->parseText(element->GetText()).c_str(), "yes"))
                        input.setRequired(true);

                if((element = (TiXmlElement*) data->FirstChild("priority")))
                    if(compareString(parser->parseText(element->GetText()).c_str(), "yes"))
                        input.setPriority(true);

                module.addInput(input);
            } // end of input data

        }

    if(root->FirstChild("services")) {
        for(TiXmlElement* services = root->FirstChild("services")->FirstChildElement();
            services; services = services->NextSiblingElement())
        {
            /* server */
            if(compareString(services->Value(), "server"))
            {
                InputData input;
                input.setPortType(SERVICE_PORT);
                TiXmlElement* element;
                if((element = (TiXmlElement*) services->FirstChild("port"))) {
                    input.setPort(parser->parseText(element->GetText()).c_str());
                    input.setCarrier("tcp");
                }
                if((element = (TiXmlElement*) services->FirstChild("description")))
                    input.setDescription(parser->parseText(element->GetText()).c_str());
                if((element = (TiXmlElement*) services->FirstChild("type")))
                    input.setName(parser->parseText(element->GetText()).c_str());
                else
                    input.setName("rpc");
                module.addInput(input);
            }
            /* client */
            if(compareString(services->Value(), "client"))
            {
                OutputData output;
                output.setPortType(SERVICE_PORT);
                TiXmlElement* element;
                if((element = (TiXmlElement*) services->FirstChild("port"))) {
                    output.setPort(parser->parseText(element->GetText()).c_str());
                    output.setCarrier("tcp");
                }
                if((element = (TiXmlElement*) services->FirstChild("description")))
                    output.setDescription(parser->parseText(element->GetText()).c_str());
                if((element = (TiXmlElement*) services->FirstChild("type")))
                    output.setName(parser->parseText(element->GetText()).c_str());
                else
                    output.setName("rpc");
                module.addOutput(output);
            }
        }

    }

    /* retrieving broker*/
    TiXmlElement* element;
    if((element = (TiXmlElement*) root->FirstChild("deployer")))
    {
        module.setBroker(parser->parseText(element->GetText()).c_str());
        module.setNeedDeployer(true);
    }

    /* retrieving dependencies*/
    if(root->FirstChild("dependencies"))
        for(TiXmlElement* restag = root->FirstChild("dependencies")->FirstChildElement();
            restag; restag = restag->NextSiblingElement())
        {
            Computer computer;
            if(compareString(restag->Value(), "computer"))
            {
                Computer computer;
                computer.setXmlFile(szFile);
                for(TiXmlElement* comptag = restag->FirstChildElement();
                    comptag; comptag = comptag->NextSiblingElement())
                {
                     /* retrieving name */
                    if(compareString(comptag->Value(), "name"))
                        computer.setName(parser->parseText(comptag->GetText()).c_str());

                    /* retrieving description */
                     if(compareString(comptag->Value(), "description"))
                        computer.setDescription(parser->parseText(comptag->GetText()).c_str());

                    // platform
                    if(compareString(comptag->Value(), "platform"))
                    {
                        Platform os;
                        TiXmlElement* element;
                        if((element = (TiXmlElement*) comptag->FirstChild("name")))
                            os.setName(parser->parseText(element->GetText()).c_str());
                        if((element = (TiXmlElement*) comptag->FirstChild("distribution")))
                            os.setDistribution(parser->parseText(element->GetText()).c_str());
                        if((element = (TiXmlElement*) comptag->FirstChild("release")))
                            os.setRelease(parser->parseText(element->GetText()).c_str());
                        computer.setPlatform(os);
                    } // end of platform tag

                    /*
                    //multiplatform
                    if(compareString(comptag->Value(), "multiplatform"))
                    {
                        MultiPlatform mltPlatform;
                        for(TiXmlElement* mptag = comptag->FirstChild("multiplatform")->FirstChildElement();
                            mptag; mptag = mptag->NextSiblingElement())
                        {
                            // platform
                            if(compareString(mptag->Value(), "platform"))
                            {
                                Platform os;
                                TiXmlElement* element;
                                if((element = (TiXmlElement*) mptag->FirstChild("name")))
                                    os.setName(element->GetText());
                                if((element = (TiXmlElement*) mptag->FirstChild("distribution")))
                                    os.setDistribution(element->GetText());
                                if((element = (TiXmlElement*) mptag->FirstChild("release")))
                                    os.setDistribution(element->GetText());
                                mltPlatform.addPlatform(os);
                            }
                        }
                        module.addResource(mltPlatform);
                    }
                    // end of multiplatform tag
                    */
                    // memory
                    if(compareString(comptag->Value(), "memory"))
                    {
                        Memory mem;
                        TiXmlElement* element;
                        if((element = (TiXmlElement*) comptag->FirstChild("total_space")))
                            mem.setTotalSpace((Capacity)atol(parser->parseText(element->GetText()).c_str()));
                        if((element = (TiXmlElement*) comptag->FirstChild("free_space")))
                            mem.setFreeSpace((Capacity)atol(parser->parseText(element->GetText()).c_str()));
                        computer.setMemory(mem);
                    } // end of memory tag

                    // storage
                    if(compareString(comptag->Value(), "storage"))
                    {
                        Storage stg;
                        TiXmlElement* element;
                        if((element = (TiXmlElement*) comptag->FirstChild("total_space")))
                            stg.setTotalSpace((Capacity)atol(parser->parseText(element->GetText()).c_str()));
                        if((element = (TiXmlElement*) comptag->FirstChild("free_space")))
                            stg.setFreeSpace((Capacity)atol(parser->parseText(element->GetText()).c_str()));
                        computer.setStorage(stg);
                    } // end of storage tag

                    // processor
                    if(compareString(comptag->Value(), "processor"))
                    {
                        Processor proc;
                        TiXmlElement* element;
                        if((element = (TiXmlElement*) comptag->FirstChild("architecture")))
                            proc.setArchitecture(parser->parseText(element->GetText()).c_str());
                        if((element = (TiXmlElement*) comptag->FirstChild("model")))
                            proc.setModel(parser->parseText(element->GetText()).c_str());
                        if((element = (TiXmlElement*) comptag->FirstChild("cores")))
                            proc.setCores((size_t)atoi(parser->parseText(element->GetText()).c_str()));
                        if((element = (TiXmlElement*) comptag->FirstChild("siblings")))
                            proc.setSiblings((size_t)atoi(parser->parseText(element->GetText()).c_str()));
                        if((element = (TiXmlElement*) comptag->FirstChild("frequency")))
                            proc.setFrequency(atof(parser->parseText(element->GetText()).c_str()));
                        computer.setProcessor(proc);
                    } // end of processor tag

                    // network
                    if(compareString(comptag->Value(), "network"))
                    {
                        Network net;
                        TiXmlElement* element;
                        if((element = (TiXmlElement*) comptag->FirstChild("ip4")))
                            net.setIP4(parser->parseText(element->GetText()).c_str());
                        if((element = (TiXmlElement*) comptag->FirstChild("ip6")))
                            net.setIP6(parser->parseText(element->GetText()).c_str());
                        if((element = (TiXmlElement*) comptag->FirstChild("mac")))
                            net.setMAC(parser->parseText(element->GetText()).c_str());
                        module.addResource(net);
                        computer.setNetwork(net);
                    } // end of network tag

                    // yarp_port
                    if(compareString(comptag->Value(), "yarp_port"))
                    {
                        ResYarpPort yport;
                        auto* element = (TiXmlElement*) comptag->FirstChild("name");
                        if(element && element->GetText())
                        {
                            yport.setName(parser->parseText(element->GetText()).c_str());
                            yport.setPort(parser->parseText(element->GetText()).c_str());
                            computer.addPeripheral(yport);
                        }
                        else
                        {
                            OSTRINGSTREAM war;
                            war<<"yarp_port from "<<szFile<<" at line " <<comptag->Row()<<" has no name.";
                            logger->addWarning(war);
                        }
                    }

                    // gpu
                    if(compareString(comptag->Value(), "gpu"))
                    {
                        GPU gpu;
                        TiXmlElement* element;
                        if((element = (TiXmlElement*) comptag->FirstChild("name")))
                            gpu.setName(parser->parseText(element->GetText()).c_str());
                        if((element = (TiXmlElement*) comptag->FirstChild("capability")))
                            gpu.setCompCompatibility(parser->parseText(element->GetText()).c_str());
                        if((element = (TiXmlElement*) comptag->FirstChild("cores")))
                            gpu.setCores((size_t)atoi(parser->parseText(element->GetText()).c_str()));
                        if((element = (TiXmlElement*) comptag->FirstChild("frequency")))
                            gpu.setFrequency(atof(parser->parseText(element->GetText()).c_str()));
                        if((element = (TiXmlElement*) comptag->FirstChild("register_block")))
                            gpu.setResgisterPerBlock((size_t)atoi(parser->parseText(element->GetText()).c_str()));
                        if((element = (TiXmlElement*) comptag->FirstChild("thread_block")))
                            gpu.setThreadPerBlock((size_t)atoi(parser->parseText(element->GetText()).c_str()));
                        if((element = (TiXmlElement*) comptag->FirstChild("overlap")))
                        {
                            if(compareString(parser->parseText(element->GetText()).c_str(), "yes"))
                                gpu.setOverlap(true);
                            else
                                gpu.setOverlap(false);
                        }


                        // global memory
                        if(comptag->FirstChild("global_memory"))
                        {
                            TiXmlElement* element;
                            element = (TiXmlElement*) comptag->FirstChild("global_memory");
                            if((element = (TiXmlElement*) element->FirstChild("total_space")))
                                gpu.setGlobalMemory((Capacity)atol(parser->parseText(element->GetText()).c_str()));
                        } // end of global memory tag

                        // shared memory
                        if(comptag->FirstChild("shared_memory"))
                        {
                            TiXmlElement* element;
                            element = (TiXmlElement*) comptag->FirstChild("shared_memory");
                            if((element = (TiXmlElement*) element->FirstChild("total_space")))
                                gpu.setSharedMemory((Capacity)atol(parser->parseText(element->GetText()).c_str()));
                        } // end of shared memory tag

                        // constant memory
                        if(comptag->FirstChild("constant_memory"))
                        {
                            TiXmlElement* element;
                            element = (TiXmlElement*) comptag->FirstChild("constant_memory");
                            if((element = (TiXmlElement*) element->FirstChild("total_space")))
                                gpu.setConstantMemory((Capacity)atol(parser->parseText(element->GetText()).c_str()));
                        } // end of shared memory tag
                        computer.addPeripheral(gpu);
                    } // end of gpu tag
                } // end of computer tag loop
                module.addResource(computer);
            } //end of if computer tag
        }// end of dependecnies tag

    return &module;
}
				/// Visit an element.
				virtual bool VisitEnter( const TiXmlElement& elt, const TiXmlAttribute* /*first_attr*/)
				{
					out << "element::VisitEnter " << elt.Value() << endl;

					string tag_name = elt.Value();
					if (tag_name == "virtual_folder")
					{
						string name = elt.Attribute("name");
						int id;
						if (TIXML_SUCCESS != elt.QueryIntAttribute("id", &id))
						{
							LERR_ << "id attribute of <virtual_folder> is not an integer (line " << elt.Row() << ")";
							return false;	
						}
						if (id >= 0)
						{
							LERR_ << "id attribute of <virtual_folder> must be negative (line " << elt.Row() << ")";
							return false;	
						}
						if (name.empty())
						{
							LERR_ << "name attribute of <virtual_folder> can't be empty (line " << elt.Row() << ")";
							return false;	
						}
	
						// check if this is root vf
						if (name == "/")
						{
							// actually create root virtual folder
							virtual_folder_pointer sp_empty;	

							// let's create the root virtual folder shared pointer
							_spcur_vf = _sproot_vf = virtual_folder::create (name, -1, sp_empty);

							//LDBG_ << "allocating root at address " << lexical_cast<string>(_sproot_vf.get());

							LDBG_ << "virtual_folder(root) : ";
							LDBG_ << "    id       : " << _spcur_vf->get_id();
							LDBG_ << "    path(act): " << _spcur_vf->get_path();
							LDBG_ << "    path(vir): " << _spcur_vf->get_path(false);
							LDBG_ << "    name     : " << _spcur_vf->get_name();
							LDBG_ << "    filetype : " << _spcur_vf->get_filetype() << std::endl;
						}
						else
						{
							// create a new virtual folder
							virtual_folder_pointer sp_new_vf = virtual_folder::create (name, id, _spcur_vf);
							//LDBG_ << "allocating " << sp_new_vf->get_path()  << " at address " << lexical_cast<string>(sp_new_vf.get());
							LDBG_ << "virtual_folder : ";
							LDBG_ << "    id       : " << sp_new_vf->get_id();
							LDBG_ << "    path(act): " << sp_new_vf->get_path();
							LDBG_ << "    path(vir): " << sp_new_vf->get_path(false);
							LDBG_ << "    name     : " << sp_new_vf->get_name();
							LDBG_ << "    filetype : " << sp_new_vf->get_filetype() << std::endl;

							// add it to current vf
							_spcur_vf->add_child(sp_new_vf);

							// now let it be the current virtual folder for next processing
							_spcur_vf = sp_new_vf;
						}
					}
					else if (tag_name == "children")
					{
					
					}
					else if (tag_name == "file")
					{
						int id;
						if (TIXML_SUCCESS != elt.QueryIntAttribute("id", &id))
						{
							LERR_ << "id attribute of <file> is not an integer (line " << elt.Row() << ")";
							return false;	
						}
						if (id < 0)
						{
							LERR_ << "id attribute of <file> must be strictly positive (line " << elt.Row() << ")";
							return false;	
						}
						_last_id = id;
					}
					else if (tag_name == "path")
					{
						int is_rel;
						if (TIXML_SUCCESS != elt.QueryIntAttribute("relative", &is_rel))
						{
							LERR_ << "relative attribute of <path> is not an integer (line " << elt.Row() << ")";
							return false;	
						}
						if (is_rel != 0 && is_rel != 1)
						{
							LERR_ << "relative attribute of <path> must be 1 or 0 (line " << elt.Row() << ")";
							return false;	
						}
						_last_is_relative = (is_rel == 1);
					}

					return true;

				}
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 &amp; 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 = '&gt;' />" );
			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 = "<doc/>";

		TiXmlDocument doc;
		doc.Parse( str );

		TiXmlElement* ele = doc.FirstChildElement();

		int iVal;
		double dVal;

		ele->SetAttribute( "str", "strValue" );
		ele->SetAttribute( "int", 1 );
		ele->SetDoubleAttribute( "double", -1.0 );

		const char* cStr = ele->Attribute( "str" );
		ele->QueryIntAttribute( "int", &iVal );
		ele->QueryDoubleAttribute( "double", &dVal );

		XmlTest( "Attribute round trip. c-string.", "strValue", cStr );
		XmlTest( "Attribute round trip. int.", 1, iVal );
		XmlTest( "Attribute round trip. double.", -1, (int)dVal );
	}
	
	{
		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( "data/utf8testout.xml", "r" );
			FILE* verify = fopen( "data/utf8testverify.xml", "r" );

			//bool firstLineBOM=true;
			if ( saved && verify )
			{
				while ( fgets( verifyBuf, 256, verify ) )
				{
					fgets( savedBuf, 256, saved );
					NullLineEndings( verifyBuf );
					NullLineEndings( savedBuf );

					if ( /*!firstLineBOM && */ strcmp( verifyBuf, savedBuf ) )
					{
						printf( "verify:%s<\n", verifyBuf );
						printf( "saved :%s<\n", savedBuf );
						okay = 0;
						break;
					}
					//firstLineBOM = false;
				}
			}
			if ( saved )
				fclose( saved );
			if ( verify )
				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 &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
				" It also has &lt;, &gt;, and &amp;, as well as a fake copyright &#xA9;.\"> </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 &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
					 " It also has &lt;, &gt;, and &amp;, 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&#xA;</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.", true, doc.Error() );	// is an  error to tinyxml (didn't use to be, but caused issues)
		//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鰊t鋘t咪鳇闹?"
                        "</?";

            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鰊t鋘t咪鳇闹?, 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>&#x0e;</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 &amp; 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 &amp; away ", c1->Value(), true );
	}
	#endif

	{
		// [ 1475201 ] TinyXML parses entities in comments
		TiXmlDocument xml;
		xml.Parse("<!-- declarations for <head> & <body> -->"
				  "<!-- far &amp; 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 &amp; away ", c1->Value(), true );
	}

	{
		TiXmlDocument xml;
		xml.Parse( "<Parent>"
						"<child1 att=''/>"
						"<!-- With this comment, child2 will not be parsed! -->"
						"<child2 att=''/>"
					"</Parent>" );
		int count = 0;

		TiXmlNode* ele = 0;
		while ( (ele = xml.FirstChildElement( "Parent" )->IterateChildren( ele ) ) != 0 ) {
			++count;
		}
		XmlTest( "Comments iterate correctly.", 3, count );
	}

	{
		// trying to repro ]1874301]. If it doesn't go into an infinite loop, all is well.
		unsigned char buf[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?><feed><![CDATA[Test XMLblablablalblbl";
		buf[60] = 239;
		buf[61] = 0;

		TiXmlDocument doc;
		doc.Parse( (const char*)buf);
	} 


	{
		// bug 1827248 Error while parsing a little bit malformed file
		// Actually not malformed - should work.
		TiXmlDocument xml;
		xml.Parse( "<attributelist> </attributelist >" );
		XmlTest( "Handle end tag whitespace", false, xml.Error() );
	}

	{
		// This one must not result in an infinite loop
		TiXmlDocument xml;
		xml.Parse( "<infinite>loop" );
		XmlTest( "Infinite loop test.", true, true );
	}

	{
		// 1709904 - can not repro the crash
		{
			TiXmlDocument xml;
			xml.Parse( "<tag>/</tag>" );
			XmlTest( "Odd XML parsing.", xml.FirstChild()->Value(), "tag" );
		}
		/* Could not repro. {
			TiXmlDocument xml;
			xml.LoadFile( "EQUI_Inventory.xml" );
			//XmlTest( "Odd XML parsing.", xml.FirstChildElement()->Value(), "XML" );
			TiXmlPrinter printer;
			xml.Accept( &printer );
			fprintf( stdout, "%s", printer.CStr() );
		}*/
	}

	/*  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;
}
Beispiel #19
0
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 &amp; 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=\"Vo&#x82;\" 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 )
	QueryPerformanceCounter( (LARGE_INTEGER*) (&start) );
	#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();
	}
	ostringstream outputStream( ostringstream::out );
        {
          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" );
          doc.Print( stdout );

          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 Dinosours!" 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", "Vo&#x82;" );
          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";
	outputStream << doc;
	XmlTest( "Output stream correct.",	string( demoEnd ).c_str(),
                 outputStream.str().c_str(), true );
#endif
        
	node = doc.RootElement();
	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 sytax.
	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 = '&gt;' />" );
		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 doc;
          doc.Parse( error );
          XmlTest( "Error row", doc.ErrorRow(), 3 );
          XmlTest( "Error column", doc.ErrorCol(), 17 );
          //printf( "error=%d id='%s' row %d col%d\n", (int) doc.Error(), doc.ErrorDesc(), doc.ErrorRow()+1, doc.ErrorCol() + 1 );
	}
	{
		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 );
	}
	{
		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 = "<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", static_cast<int>(dVal), 1 );
		result = ele->QueryDoubleAttribute( "attr1", &dVal );
		XmlTest( "Query attribute: double as double", static_cast<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 );
	}

#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

	//////////////////////////////////////////////////////
#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 );
#endif

	//////////////////////////////////////////////////////
	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
			// verifing 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" );
		doc.LoadFile();
		// 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 &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
				" It also has &lt;, &gt;, and &amp;, as well as a fake &#xA9;.\"> </psg>"
			"</passages>";

		TiXmlDocument doc( "passages.xml" );
		doc.Parse( passages );
		TiXmlElement* psg = doc.RootElement()->FirstChildElement();
		const char* context = psg->Attribute( "context" );

		XmlTest( "Entity transformation: read. ",
					"Line 5 has \"quotation marks\" and 'apostrophe marks'."
					" It also has <, >, and &, as well as a fake \xA9.",
					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 &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
					 " It also has &lt;, &gt;, and &amp;, as well as a fake &#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&#xA;</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" );
		}
    }


	#if defined( WIN32 ) && defined( TUNE )
	QueryPerformanceCounter( (LARGE_INTEGER*) (&end) );
	QueryPerformanceFrequency( (LARGE_INTEGER*) (&freq) );
	printf( "Time for run: %f\n", ( double )( end-start ) / (double) freq );
	#endif

	printf ("\nPass %d, Fail %d\n", gPass, gFail);
	return gFail;
}