Example #1
0
bool CSimpleXml::ModifyXml(list<XMLNODEINFO> &lstXmlNodes)
{
    if(m_pDoc == NULL || m_pRoot == NULL)
    {
        return false;
    }
    list<XMLNODEINFO>::iterator itlist = lstXmlNodes.begin();
    int nSize = lstXmlNodes.size();
    for(int i = 0; i < nSize; ++i)
    {
        if(!AccessXmlNode((*itlist), MODIFY))
        {
            return false;
        }
        ++itlist;
    }
    TiXmlPrinter printer;
    printer.SetStreamPrinting();
    if(m_pDoc->Accept( &printer ))
    {
        m_strXml = printer.CStr();
    }
    else
    {
        return false;
    }
    return true;
}
Example #2
0
bool CSimpleXml::OpenXml(const string &strXml, int nXmlType)
{
	if(strXml.empty())
	{
		return false;
	}
//	m_pDoc = new TiXmlDocument(strXml.c_str());
	if(XMLFILE == nXmlType)//解析文件
	{
            m_pDoc = new TiXmlDocument(strXml.c_str());
		if(!m_pDoc->LoadFile())  
		{
			return false;
		}
	}
	else if(XMLSTR == nXmlType)//解析字符串
	{
            m_pDoc = new TiXmlDocument;
		 m_pDoc->Parse(strXml.c_str());
	}
	m_pRoot = m_pDoc->RootElement(); 
	if(NULL == m_pDoc || NULL == m_pRoot)
	{
		return false;
	}
	TiXmlPrinter printer;
	printer.SetStreamPrinting();
	if(m_pDoc->Accept(&printer))
	{
		m_strXml = printer.CStr();
		return true;
	}
	return false;
}
// QC:A (discussion possible sur l'utilisation de snprintf. Les buffers statiques ne sont pas thread safe.)
char* ScriptVariable::getstr() const {
	if(isPointer()) {
		return getPointee()->getstr();
	}

	if(type == VAR_NULL) {
		return NULL;
	}

	if(type == VAR_INT) {
		static char number[32];
		snprintf(number, 32, "%d", value);
		number[31] ='\0';
		return number;
	}

	if(type == VAR_XML) {
		static TiXmlPrinter printer;
		printer = TiXmlPrinter();
		printer.SetStreamPrinting();
		TiXmlNode* node = (TiXmlNode*) data;
		node->Accept(&printer);
		return (char*)printer.CStr();
	}

	if(type == VAR_OBJ) {
		static char address[256];
		snprintf(address, 256, "(*%p:%s)", data, ((ScriptableObject*)data)->getClassName());
		address[255] ='\0';
		return address;
	}

	if(type == VAR_PAIR) {
		static char number[64];
		snprintf(number, 64, "(%ld:%ld)", (long) data, (long) params);
		number[63] ='\0';
		return number;
	}

	if(type == VAR_PACK) {
		static char info[4096]; // XXX : NOT thread safe
		snprintf(info, 4096, "(*%p => \"%s\")", data, params);
		info[4095] ='\0';
		return info;
	}

	if(type == VAR_TBL) {
		static char info[4096]; // XXX : NOT thread safe
		snprintf(info, 4096, "(tbl[%ld]:*%p)", (long)(data?(((ScriptTable*)data)->size()):0), data);
		info[4095] ='\0';
		return info;
	}

	if(type == VAR_FCT) {
		return params;
	}

	return data;
}
size_t XMLSource::getText(const char*& outputBuffer) {
	TiXmlPrinter printer;
	printer.SetStreamPrinting();
	xassert(doc, "No document to save.");
	doc->Accept(&printer);
	outputBuffer = printer.CStr();
	return printer.Size();
}
// QC:?
void ScriptableObject::saveAOD(VFS::File* file)
{
	TiXmlDocument* doc = new TiXmlDocument();
	TiXmlElement* xml = aod()->Clone()->ToElement();

	cleanPtrInAOD(xml);
	doc->LinkEndChild(xml);

	TiXmlPrinter printer;
	printer.SetStreamPrinting();
	doc->Accept(&printer);

	file->truncate();
	file->write((char*)printer.CStr(), printer.Size());

	delete doc;
}
Example #6
0
void ProcessFile(const char* fileName)
{
    TiXmlDocument doc;
    doc.LoadFile(fileName);
    if (doc.Error())
    {
        printf("Error in file %s: %s\n", fileName, doc.ErrorDesc());
        return;
    }
    TiXmlPrinter printer;
    printer.SetStreamPrinting();
    doc.Accept(&printer);

    FILE *f = fopen(fileName, "wb");
    if (!f)
        return;

    fwrite(printer.CStr(), printer.Size(), 1, f);
    fclose(f);
}
Example #7
0
/**************************************************************************
* name       : GetXMLStream
* description: 获取xml流
* input      : NA
* output     : nXMLStreamLength
* return     : const char* xml流
* remark     : NA
**************************************************************************/
const char*  CXml::GetXMLStream(unsigned int &uiXMLStreamLength)
{
	TiXmlPrinter xmlPrinter;
	xmlPrinter.SetStreamPrinting();		

	if (NULL == m_pXMlDoc)
	{
		SAFE_NEW(m_pXMlDoc, TiXmlDocument);//lint !e774
	}

	CHECK_POINTER(m_pXMlDoc, NULL);//lint !e774
	if (!m_pXMlDoc->Accept(&xmlPrinter))
	{
		return NULL;
	}

    uiXMLStreamLength = xmlPrinter.Size();

	m_strStream = xmlPrinter.CStr();
    return m_strStream.c_str();
}
Example #8
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 )
		_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;
}
Example #9
0
HRESULT CHVC::BuildPlateString(
    char* pszPlateString,
    int* piPlateStringSize,
    CARLEFT_INFO_STRUCT *pCarLeftInfo
)
{
    if (pCarLeftInfo == NULL || pszPlateString == NULL || piPlateStringSize == NULL) return E_INVALIDARG;

    if (!m_pXmlDoc)	//如果文档为空则创建新文档
    {
        m_pXmlDoc = new TiXmlDocument;
        TiXmlDeclaration* pDecl = new TiXmlDeclaration("1.0", "GB2312", "yes");
        TiXmlElement* pRoot = new TiXmlElement("HvcResultDoc");

        if ( !m_pXmlDoc || !pDecl || !pRoot )
        {
            SAFE_DELETE(m_pXmlDoc);
            SAFE_DELETE(pDecl);
            SAFE_DELETE(pRoot);
            return E_OUTOFMEMORY;
        }

        m_pXmlDoc->LinkEndChild(pDecl);
        m_pXmlDoc->LinkEndChild(pRoot);
    }

    //取得ResultSet段
    TiXmlElement* pResultSet = m_pXmlDoc->RootElement()->FirstChildElement("ResultSet");
    if (!pResultSet)
    {
        pResultSet = new TiXmlElement("ResultSet");
        if ( !pResultSet ) return E_OUTOFMEMORY;
        m_pXmlDoc->RootElement()->LinkEndChild(pResultSet);
    }

    //注意:一定要删除已经存在的节
    TiXmlNode* pResultOld = pResultSet->FirstChild("Result");
    if ( pResultOld )
    {
        pResultSet->RemoveChild(pResultOld);
    }

    //写入Result
    TiXmlElement* pResult = new TiXmlElement("Result");
    if (pResult)
    {
        pResultSet->LinkEndChild(pResult);

        //车牌
        char szConf[32] = {0};
        char szPlateName[32] = {0};
        char szFrameName[64] = {0};

        GetPlateNameAlpha(
            (char*)szPlateName,
            ( PLATE_TYPE )pCarLeftInfo->cCoreResult.nType,
            ( PLATE_COLOR )pCarLeftInfo->cCoreResult.nColor,
            pCarLeftInfo->cCoreResult.rgbContent
        );

        if (strstr(szPlateName, "11111") != NULL)
        {
            HV_Trace(5, "M");
            //return S_FALSE;
        }

        HV_Trace(5,"%s\n", szPlateName);  //输出车牌字符串
        TiXmlElement* pValue = new TiXmlElement("PlateName");
        TiXmlText* pText = new TiXmlText(szPlateName);
        if (pValue && pText)
        {
            pValue->LinkEndChild(pText);
            pResult->LinkEndChild(pValue);
        }

        int nColorType = 0;
        if (strncmp(szPlateName, "蓝", 2) == 0)
        {
            nColorType = 1;
        }
        else if (strncmp(szPlateName, "黄", 2) == 0)
        {
            nColorType = 2;
        }
        else if (strncmp(szPlateName, "黑", 2) == 0)
        {
            nColorType = 3;
        }
        else if (strncmp(szPlateName, "白", 2) == 0)
        {
            nColorType = 4;
        }
        else if (strncmp(szPlateName, "绿", 2) == 0)
        {
            nColorType = 5;
        }
        else
        {
            nColorType = 0;
        }

        int nPlateType = 0;
        switch ( pCarLeftInfo->cCoreResult.nType )
        {
        case PLATE_NORMAL:
        case PLATE_POLICE:
            nPlateType = 1;
            break;
        case PLATE_WJ:
            nPlateType = 2;
            break;
        case PLATE_POLICE2:
            nPlateType = 3;
            break;
        case PLATE_DOUBLE_YELLOW:
        case PLATE_DOUBLE_MOTO:
            nPlateType = 4;
            break;
        default:
            nPlateType = 0;
            break;
        }

        pValue = new TiXmlElement("Color");
        if ( pValue )
        {
            pValue->SetAttribute("raw_value", pCarLeftInfo->cCoreResult.nColor);
            pValue->SetAttribute("value", nColorType);
            pResult->LinkEndChild(pValue);
        }

        pValue = new TiXmlElement("Type");
        if ( pValue )
        {
            pValue->SetAttribute("raw_value", pCarLeftInfo->cCoreResult.nType);
            pValue->SetAttribute("value", nPlateType);
            pResult->LinkEndChild(pValue);
        }

        //如果输出附加信息
        if (m_cModuleParams.cResultSenderParam.fOutputAppendInfo)
        {
            if (m_cModuleParams.cResultSenderParam.fOutputObservedFrames)
            {
                //有效帧数
                pValue = new TiXmlElement("ObservedFrames");
                if (pValue)
                {
                    pValue->SetAttribute("value", "1");
                    pValue->SetAttribute("chnname", "有效帧数");
                    pResult->LinkEndChild(pValue);
                }
            }

            //可信度
            pValue = new TiXmlElement("Confidence");
            if (pValue)
            {
                sprintf(szConf, "%.3f", exp(log(pCarLeftInfo->cCoreResult.fltAverageConfidence) * 0.143));
                pValue->SetAttribute("value", szConf);
                pValue->SetAttribute("chnname", "平均可信度");
                pResult->LinkEndChild(pValue);
            }

            //首字符可信度
            pValue = new TiXmlElement("FirstCharConf");
            if (pValue)
            {
                sprintf(szConf, "%.3f", pCarLeftInfo->cCoreResult.fltFirstAverageConfidence);
                pValue->SetAttribute("value", szConf);
                pValue->SetAttribute("chnname", "首字可信度");
                pResult->LinkEndChild(pValue);
            }

            //车身颜色
            if (m_cModuleParams.cTrackerCfgParam.fEnableRecgCarColor)
            {
                pValue = new TiXmlElement("CarColor");
                if (pValue)
                {
                    GetCarColor(pCarLeftInfo, szConf);
                    pValue->SetAttribute("value", szConf);
                    pValue->SetAttribute("chnname", "车身颜色");
                    pResult->LinkEndChild(pValue);
                }
            }

            //车牌HSL值
            if(m_cModuleParams.cTrackerCfgParam.fProcessPlate_BlackPlate_Enable) //黑牌参数使能
            {
                pValue = new TiXmlElement("HSL");
                if (pValue)
                {
                    HV_Trace(5,"---AppendInfo:H:%d\tS:%d\tL:%d\n", pCarLeftInfo->cCoreResult.iH, pCarLeftInfo->cCoreResult.iS, pCarLeftInfo->cCoreResult.iL);
                    sprintf(szConf, "H:%d\tS:%d\tL:%d", pCarLeftInfo->cCoreResult.iH, pCarLeftInfo->cCoreResult.iS, pCarLeftInfo->cCoreResult.iL);
                    pValue->SetAttribute("value", szConf);
                    pValue->SetAttribute("chnname", "车牌HSL值");
                    pResult->LinkEndChild(pValue);
                }
            }


            //处理时间
            DWORD32 dwProcTime = GetSystemTick() - pCarLeftInfo->cCoreResult.cResultImg.pimgBestSnapShot->GetRefTime();
            if (dwProcTime > 180)
            {
                dwProcTime = 180 - DWORD32(1 + (54.0 * rand() / (RAND_MAX + 1.0)) - 27);
            }
            pValue = new TiXmlElement("ProcTime");
            if (pValue)
            {
                sprintf(szConf, "%d", dwProcTime);
                pValue->SetAttribute("value", szConf);
                pValue->SetAttribute("chnname", "处理时间");
                pResult->LinkEndChild(pValue);
            }

        } // end of if (m_cModuleParams.cResultSenderParam.fOutputAppendInfo)
    } // end of if (pResult)

    TiXmlPrinter cTxPr;
    if (m_pXmlDoc)
    {
        cTxPr.SetStreamPrinting();
        m_pXmlDoc->Accept(&cTxPr);

        int nCpyLen = MIN_INT(*piPlateStringSize, (int)cTxPr.Size() + 1);
        HV_memcpy( pszPlateString, cTxPr.CStr(), nCpyLen );
        pszPlateString[nCpyLen - 1] = '\0';
        *piPlateStringSize = nCpyLen;
    }
    else
    {
        *piPlateStringSize = 0;
    }

    return S_OK;
}
Example #10
0
Atlas::Message::MapType EntityRecipe::createEntity(Eris::TypeService& typeService)
{
	S_LOG_VERBOSE("Creating entity.");

	ScriptingService& scriptingService = EmberServices::getSingleton().getScriptingService();
	// Loading script code
	scriptingService.executeCode(mScript, "LuaScriptingProvider");

	// Walking through adapter bindings
	for (BindingsStore::iterator I = mBindings.begin(); I != mBindings.end(); ++I) {
		const std::string& func = I->second->getFunc();

		S_LOG_VERBOSE(" binding: " << I->first << " to func " << func);

		if (func.empty()) {
			std::vector<std::string>& adapters = I->second->getAdapters();

			if (adapters.size() == 1) {
				std::string adapterName = adapters[0];
				Atlas::Message::Element val = mGUIAdapters[adapterName]->getValue();
				I->second->setValue(val);
			} else {
				S_LOG_WARNING("Should be only one adapter without calling function.");
			}
		} else {
			Lua::LuaScriptingCallContext callContext;

			lua_State* L = static_cast<Lua::LuaScriptingProvider*> (scriptingService.getProviderFor("LuaScriptingProvider"))->getLuaState();

			// Pushing function params
			std::vector<std::string>& adapters = I->second->getAdapters();
			for (std::vector<std::string>::iterator J = adapters.begin(); J != adapters.end(); J++) {
				std::string adapterName = *J;
				Atlas::Message::Element* val = new Atlas::Message::Element(mGUIAdapters[adapterName]->getValue());
				tolua_pushusertype_and_takeownership(L, val, "Atlas::Message::Element");
			}

			// Calling test function
			scriptingService.callFunction(func, adapters.size(), "LuaScriptingProvider", &callContext);

			LuaRef returnValue(callContext.getReturnValue());

			Atlas::Message::Element returnObj;
			returnObj = returnValue.asObject<Atlas::Message::Element> ("Atlas::Message::Element");
			I->second->setValue(returnObj);
		}
	}
	//Inject all default attributes that aren't yet added.
	// 	TiXmlElement *elem = mEntitySpec->FirstChildElement("atlas");
	// 	if (elem)
	// 	{
	// 		Eris::TypeInfo* erisType = mConn->getTypeService()->getTypeByName(getEntityType());
	// 		if (erisType) {
	// 			const Atlas::Message::MapType& defaultAttributes = erisType->getAttributes();
	// 			for (Atlas::Message::MapType::const_iterator I = defaultAttributes.begin(); I != defaultAttributes.end(); ++I) {
	// 				bool hasAttribute = false;
	// 				TiXmlNode* child(0);
	// 				while(child = elem->IterateChildren(child)) {
	// 					if (child->ToElement()) {
	// 						if (std::string(child->ToElement()->Attribute("name")) == I->first) {
	// 							hasAttribute = true;
	// 							break;
	// 						}
	// 					}
	// 				}
	//
	// 				if (!hasAttribute) {
	// 					//The attribute isn't present, we'll inject it
	// 					//This a bit contrived, since we'll now first convert the atlas into xml and inject it into the TiXmlElement (which will convert the xml strings into TiXml structures). And then later on we'll parse the xml again and create the final atlas data from it. However, the main reason for doing it this way is that in the future we would want to have nested child elements, which could be repeated. And in those cases we'll want to work directly with xml.
	// 				}
	// 			}
	// 		}
	// 	}
	/*
	 std::stringstream str;

	 Atlas::Message::Element element(message);

	 Atlas::Message::QueuedDecoder decoder;

	 Atlas::Codecs::XML codec(str, decoder);
	 Atlas::Formatter formatter(str, codec);
	 Atlas::Message::Encoder encoder(formatter);
	 formatter.streamBegin();
	 encoder.streamMessageElement(message);
	 formatter.streamEnd();
	 */
	if (mEntitySpec) {
		// Print entity into string
		TiXmlPrinter printer;
		printer.SetStreamPrinting();
		mEntitySpec->Accept(&printer);

		S_LOG_VERBOSE("Composed entity: " << printer.Str());

		std::stringstream strStream(printer.CStr(), std::ios::in);

		// Create objects
		Atlas::Message::QueuedDecoder decoder;
		Atlas::Codecs::XML codec(strStream, decoder);

		// Read whole stream into decoder queue
		while (!strStream.eof()) {
			codec.poll();
		}

		// Read decoder queue
		while (decoder.queueSize() > 0) {
			Atlas::Message::MapType m = decoder.popMessage();
			Eris::TypeInfo* erisType = typeService.getTypeByName(getEntityType());
			if (erisType) {
				const Atlas::Message::MapType& defaultAttributes = erisType->getAttributes();
				for (Atlas::Message::MapType::const_iterator I = defaultAttributes.begin(); I != defaultAttributes.end(); ++I) {
					if (m.find(I->first) == m.end()) {
						m.insert(Atlas::Message::MapType::value_type(I->first, I->second));
					}
				}
			}
			return m;
		}
	} else {
		Atlas::Message::MapType msg;
		msg["parents"] = Atlas::Message::ListType(1, mEntityType);
		msg["name"] = getName();
		return msg;
	}
	S_LOG_WARNING("No entity composed");
	return Atlas::Message::MapType();
}
    int ServiceLogicFacade::Trace(struct soap* soap, _ns2__Trace* request, _ns2__TraceResponse* response) const {
        
        RasterImage* rasterImage = NULL;
        VectorImage* vectorImage = NULL;
        TiXmlDocument* svgXmlDocument = NULL;

        try {
        
            if (!securityModule->CheckSystemID(request->authToken)) {
                response->statusCode = StatusCodes::FORBIDDEN;
                logger->LogMessage("Authentication token {" + request->authToken + "} is invalid. Access denied.");
                return SOAP_OK;
            }

            //decode image data from base64
            string decodedImgData;

            bool encodingSuccessful = Base64::Decode(request->imageData, decodedImgData);

            if (!encodingSuccessful) {
                response->statusCode = StatusCodes::DECODING_ERROR;
                goto CLEANUP;
            }

            istringstream sourceImageStream(decodedImgData);

            //create RasterImage instance

            try {
                rasterImage = WinBMP::FromStream(sourceImageStream);
            }
            catch (const ImTrcr::Imaging::InvalidBmpStreamException& ex) {
                response->statusCode = StatusCodes::WRONG_FORMAT_ERROR;
                logger->LogMessage("Wrong format of received image. Vectorization failed. Authentication token of external system is {" + request->authToken + "}.");
                goto CLEANUP;
            }
            catch (...) {
                response->statusCode = StatusCodes::WRONG_FORMAT_ERROR;
                logger->LogMessage("Wrong format of received image. Vectorization failed. Authentication token of external system is {" + request->authToken + "}.");
                goto CLEANUP;
            }

            TracingOptions opts;
            if (!StringUtils::TryParseInt(request->despecklingPixels, opts.despecklingPixels)) {
                response->statusCode = StatusCodes::WRONG_FORMAT_ERROR;
                goto CLEANUP;
            }
            if (!StringUtils::TryParseInt(request->angularity, opts.angularity)) {
                response->statusCode = StatusCodes::WRONG_FORMAT_ERROR;
                goto CLEANUP;
            }

            //trace RasterImage instance to VectorImage instance
            try {
                vectorImage = tracer->Trace(*rasterImage, opts);
            }
            catch (...) {
                response->statusCode = StatusCodes::TRACING_ERROR;
                goto CLEANUP;
            }

            //serialize VectorImage to SVG XML and put it into response object
            svgXmlDocument = svgSerializer->Serialize(*vectorImage);

            TiXmlPrinter printer;
            printer.SetStreamPrinting();
            svgXmlDocument->Accept(&printer);
            response->svgXml = printer.CStr();
            response->statusCode = StatusCodes::OK;
            goto CLEANUP;
        }
        catch (...) {
            response->statusCode = StatusCodes::UNKNOWN_ERROR;
            goto CLEANUP;
        }

    CLEANUP:
        MemoryUtils::SafeFree(&rasterImage);
        MemoryUtils::SafeFree(&vectorImage);
        MemoryUtils::SafeFree(&svgXmlDocument);

        return SOAP_OK;
    }
Example #12
0
HRESULT CTrafficGate::BuildPlateString(
    char* pszPlateString,
    int* piPlateStringSize,
    CARLEFT_INFO_STRUCT *pCarLeftInfo
)
{
    if (pCarLeftInfo == NULL || pszPlateString == NULL || piPlateStringSize == NULL) return E_INVALIDARG;

    if (!m_pXmlDoc)	//如果文档为空则创建新文档
    {
        m_pXmlDoc = new TiXmlDocument;
        TiXmlDeclaration* pDecl = new TiXmlDeclaration("1.0", "GB2312", "yes");
        TiXmlElement* pRoot = new TiXmlElement("HvcResultDoc");

        if ( !m_pXmlDoc || !pDecl || !pRoot )
        {
            SAFE_DELETE(m_pXmlDoc);
            SAFE_DELETE(pDecl);
            SAFE_DELETE(pRoot);
            return E_OUTOFMEMORY;
        }

        m_pXmlDoc->LinkEndChild(pDecl);
        m_pXmlDoc->LinkEndChild(pRoot);
    }

    //取得ResultSet段
    TiXmlElement* pResultSet = m_pXmlDoc->RootElement()->FirstChildElement("ResultSet");
    if (!pResultSet)
    {
        pResultSet = new TiXmlElement("ResultSet");
        if ( !pResultSet ) return E_OUTOFMEMORY;
        m_pXmlDoc->RootElement()->LinkEndChild(pResultSet);
    }

    //注意:一定要删除已经存在的节
    TiXmlNode* pResultOld = pResultSet->FirstChild("Result");
    if ( pResultOld )
    {
        pResultSet->RemoveChild(pResultOld);
    }

    //写入Result
    TiXmlElement* pResult = new TiXmlElement("Result");
    if (pResult)
    {
        pResultSet->LinkEndChild(pResult);

        //车牌
        static char szConf[128] = {0};
        static char szPlateName[32] = {0};
        static char szFrameName[64] = {0};
        static char szCarType[16] = {0};
        bool fIsNoPlate = false;
        bool fIsCar = true;
        bool fIsDouble = false;
        bool fIsDoubleMoto = false;

        GetPlateNameAlpha(
            (char*)szPlateName,
            ( PLATE_TYPE )pCarLeftInfo->cCoreResult.nType,
            ( PLATE_COLOR )pCarLeftInfo->cCoreResult.nColor,
            pCarLeftInfo->cCoreResult.rgbContent
        );

        if (strstr(szPlateName, "11111") != NULL)
        {
            HV_Trace(5, "M");
            return S_FALSE;
        }

        //获取车辆类型
        GetCarType(&pCarLeftInfo->cCoreResult, szCarType);

        //车辆类型为行人、或者非机动车时,将"无车牌"替换为车辆类型
        if (strcmp(szCarType, "行人") == 0
                || strcmp(szCarType, "非机动车") == 0)
        {
            strcpy(szPlateName, "  ");
            strcat(szPlateName, szCarType);
            fIsCar = false;
        }

        if (pCarLeftInfo->cCoreResult.nType == PLATE_DOUBLE_YELLOW)
        {
            fIsDouble = true;
        }
        if (pCarLeftInfo->cCoreResult.nType == PLATE_DOUBLE_MOTO)
        {
            fIsDoubleMoto = true;
        }

        HV_Trace(5, "%s\n", szPlateName);  //输出车牌字符串

        //无牌车
        if ((*(pCarLeftInfo->cCoreResult.rgbContent)) == 0)
        {
            fIsNoPlate = true;
        }

        TiXmlElement* pValue = new TiXmlElement("PlateName");
        TiXmlText* pText = new TiXmlText(szPlateName);
        if (pValue && pText)
        {
            pValue->LinkEndChild(pText);
            pResult->LinkEndChild(pValue);
        }

        int nColorType = 0;
        if (strncmp(szPlateName, "蓝", 2) == 0)
        {
            nColorType = 1;
        }
        else if (strncmp(szPlateName, "黄", 2) == 0)
        {
            nColorType = 2;
        }
        else if (strncmp(szPlateName, "黑", 2) == 0)
        {
            nColorType = 3;
        }
        else if (strncmp(szPlateName, "白", 2) == 0)
        {
            nColorType = 4;
        }
        else if (strncmp(szPlateName, "绿", 2) == 0)
        {
            nColorType = 5;
        }
        else
        {
            nColorType = 0;
        }

        int nPlateType = 0;
        switch ( pCarLeftInfo->cCoreResult.nType )
        {
        case PLATE_NORMAL:
        case PLATE_POLICE:
            nPlateType = 1;
            break;
        case PLATE_WJ:
            nPlateType = 2;
            break;
        case PLATE_POLICE2:
            nPlateType = 3;
            break;
        case PLATE_DOUBLE_YELLOW:
        case PLATE_DOUBLE_MOTO:
            nPlateType = 4;
            break;
        default:
            nPlateType = 0;
            break;
        }

        pValue = new TiXmlElement("Color");
        if ( pValue )
        {
            pValue->SetAttribute("raw_value", pCarLeftInfo->cCoreResult.nColor);
            pValue->SetAttribute("value", nColorType);
            pResult->LinkEndChild(pValue);
        }

        pValue = new TiXmlElement("Type");
        if ( pValue )
        {
            pValue->SetAttribute("raw_value", pCarLeftInfo->cCoreResult.nType);
            pValue->SetAttribute("value", nPlateType);
            pResult->LinkEndChild(pValue);
        }

        //如果输出附加信息
        if (m_cModuleParams.cResultSenderParam.fOutputAppendInfo)
        {
            //输出车辆逆行标识
            if (m_cModuleParams.cTrackerCfgParam.nDetReverseRunEnable)
            {
                pValue = new TiXmlElement("ReverseRun");
                if (pValue)
                {
                    sprintf(szConf, "%s", pCarLeftInfo->cCoreResult.fReverseRun ? "是" : "否");
                    pValue->SetAttribute("value", szConf);
                    pValue->SetAttribute("chnname", "车辆逆向行驶");
                    pResult->LinkEndChild(pValue);
                }
            }

            //如果无车牌则将速度值取随机,车身颜色为灰色
            if (fIsNoPlate && fIsCar)
            {
                if (m_cModuleParams.cTrackerCfgParam.cScaleSpeed.fEnable)
                {
                    srand(GetSystemTick());
                    pCarLeftInfo->cCoreResult.fltCarspeed = rand() % 20 + 20.0f;
                }
                pCarLeftInfo->cCoreResult.nCarColor = CC_GREY;
            }
            //输出速度值
            if (pCarLeftInfo->cCoreResult.fltCarspeed > 0.0f)
            {
                pValue = new TiXmlElement("VideoScaleSpeed");
                if (pValue)
                {
                    sprintf(szConf, "%d Km/h", (int)(pCarLeftInfo->cCoreResult.fltCarspeed));
                    pValue->SetAttribute("value", szConf);
                    pValue->SetAttribute("chnname", "视频测速");
                    pResult->LinkEndChild(pValue);
                }
                //如果有事件检测功能,则把限速值发出去
                if (pCarLeftInfo->cCoreResult.nDetectCrossLineEnable
                        || pCarLeftInfo->cCoreResult.nDetectOverYellowLineEnable)
                {
                    pValue = new TiXmlElement("SpeedLimit");
                    if (pValue)
                    {
                        sprintf(szConf, "%d Km/h", m_cModuleParams.cResultSenderParam.iSpeedLimit);
                        pValue->SetAttribute("value", szConf);
                        pValue->SetAttribute("chnname", "限速值");
                        pResult->LinkEndChild(pValue);
                    }
                }
                //距离计算的误差比例
                pValue = new TiXmlElement("ScaleSpeedOfDistance");
                if (pValue)
                {
                    sprintf(szConf, "%0.2f", pCarLeftInfo->cCoreResult.fltScaleOfDistance);
                    pValue->SetAttribute("value", szConf);
                    pValue->SetAttribute("chnname", "距离测量误差比例");
                    pResult->LinkEndChild(pValue);
                }
            }

            if (m_cModuleParams.cResultSenderParam.fOutputObservedFrames)
            {
                //有效帧数
                pValue = new TiXmlElement("ObservedFrames");
                if (pValue)
                {
                    sprintf(szConf, "%d", pCarLeftInfo->cCoreResult.iObservedFrames);
                    pValue->SetAttribute("value", szConf);
                    pValue->SetAttribute("chnname", "有效帧数");
                    pResult->LinkEndChild(pValue);
                }

                //可信度
                pValue = new TiXmlElement("Confidence");
                if (pValue)
                {
                    sprintf(
                        szConf, "%.3f",
                        exp(log(pCarLeftInfo->cCoreResult.fltAverageConfidence) * 0.143)
                    );
                    pValue->SetAttribute("value", szConf);
                    pValue->SetAttribute("chnname", "平均可信度");
                    pResult->LinkEndChild(pValue);
                }

                //首字符可信度
                pValue = new TiXmlElement("FirstCharConf");
                if (pValue)
                {
                    sprintf(szConf, "%.3f", pCarLeftInfo->cCoreResult.fltFirstAverageConfidence);
                    pValue->SetAttribute("value", szConf);
                    pValue->SetAttribute("chnname", "首字可信度");
                    pResult->LinkEndChild(pValue);
                }
            }

            //车辆检测时间
            if (m_cModuleParams.cResultSenderParam.fOutputCarArriveTime)
            {
                pValue = new TiXmlElement("CarArriveTime");
                if (pValue)
                {
                    sprintf(szConf, "%u", pCarLeftInfo->cCoreResult.nFirstFrameTime);
                    pValue->SetAttribute("value", szConf);
                    pValue->SetAttribute("chnname", "车辆检测时间");
                    pResult->LinkEndChild(pValue);
                }
            }

            if (fIsDouble)
            {
                //双层牌
                pValue = new TiXmlElement("DoublePlate");
                if (pValue)
                {
                    pValue->SetAttribute("value", "双");
                    pValue->SetAttribute("chnname", "车牌类型");
                    pResult->LinkEndChild(pValue);
                }
            }

            if (fIsDoubleMoto)
            {
                //摩托
                pValue = new TiXmlElement("DoubleMoto");
                if (pValue)
                {
                    pValue->SetAttribute("value", "摩");
                    pValue->SetAttribute("chnname", "车牌类型");
                    pResult->LinkEndChild(pValue);
                }
            }

            //环境光亮度
            pValue = new TiXmlElement("AmbientLight");
            if (pValue)
            {
                sprintf(szConf, "%d", pCarLeftInfo->cCoreResult.iAvgY);
                pValue->SetAttribute("value", szConf);
                pValue->SetAttribute("chnname", "环境亮度");
                pResult->LinkEndChild(pValue);
            }

            //车牌亮度
            pValue = new TiXmlElement("PlateLight");
            if (pValue)
            {
                sprintf(szConf, "%d", pCarLeftInfo->cCoreResult.iCarAvgY);
                pValue->SetAttribute("value", szConf);
                pValue->SetAttribute("chnname", "车牌亮度");
                pResult->LinkEndChild(pValue);
            }

            //车牌对比度
            pValue = new TiXmlElement("PlateVariance");
            if (pValue)
            {
                sprintf(szConf, "%d", pCarLeftInfo->cCoreResult.iCarVariance);
                pValue->SetAttribute("value", szConf);
                pValue->SetAttribute("chnname", "车牌对比度");
                pResult->LinkEndChild(pValue);
            }

            //车辆尺寸
            if (m_cModuleParams.cTrackerCfgParam.fOutputCarSize
                    && pCarLeftInfo->cCoreResult.nCarType != CT_WALKMAN
                    && pCarLeftInfo->cCoreResult.nCarType != CT_BIKE
                    && pCarLeftInfo->cCoreResult.nType != PLATE_DOUBLE_MOTO)
            {
                pValue = new TiXmlElement("CarSize");
                if (pValue)
                {
                    if (pCarLeftInfo->cCoreResult.cCarSize.nOutType == 0)
                    {
                        sprintf(
                            szConf, "%d 车长(像素):%d",
                            (int)pCarLeftInfo->cCoreResult.cCarSize.iCarWidth,
                            (int)pCarLeftInfo->cCoreResult.cCarSize.iCarHeight
                        );
                    }
                    else
                    {
                        sprintf(
                            szConf, "%.2f 车长(米):%.2f",
                            pCarLeftInfo->cCoreResult.cCarSize.iCarWidth,
                            pCarLeftInfo->cCoreResult.cCarSize.iCarHeight
                        );
                    }
                    pValue->SetAttribute("value", szConf);
                    sprintf(
                        szConf, "车宽(%s)",
                        pCarLeftInfo->cCoreResult.cCarSize.nOutType == 0 ? "像素" : "米"
                    );
                    pValue->SetAttribute("chnname", szConf);
                    pResult->LinkEndChild(pValue);
                }
            }

            //车辆类型
            pValue = new TiXmlElement("CarType");
            if (pValue)
            {
                pValue->SetAttribute("value", szCarType);
                pValue->SetAttribute("chnname", "车辆类型");
                pResult->LinkEndChild(pValue);
            }

            //车身颜色
            if (m_cModuleParams.cTrackerCfgParam.fEnableRecgCarColor)
            {
                pValue = new TiXmlElement("CarColor");
                if (pValue)
                {
                    GetCarColor(pCarLeftInfo, szConf);
                    pValue->SetAttribute("value", szConf);
                    pValue->SetAttribute("chnname", "车身颜色");
                    pResult->LinkEndChild(pValue);
                }
            }

            //车道号
            pValue = new TiXmlElement("RoadNumber");
            if (pValue)
            {
                if (m_cModuleParams.cTrackerCfgParam.iStartRoadNum == 0)
                {
                    sprintf(szConf, "%d", pCarLeftInfo->cCoreResult.nRoadNo);
                }
                else
                {
                    if (pCarLeftInfo->cCoreResult.nRoadNo == 255)
                    {
                        sprintf(szConf, "%d", pCarLeftInfo->cCoreResult.nRoadNo);
                    }
                    else
                    {
                        sprintf(szConf, "%d", pCarLeftInfo->cCoreResult.nRoadNo + 1);
                    }
                }
                pValue->SetAttribute("value", szConf);
                pValue->SetAttribute("chnname", "车道");
                pResult->LinkEndChild(pValue);
            }

            //起始车道号
            pValue = new TiXmlElement("BeginRoadNumber");
            if (pValue)
            {
                if (m_cModuleParams.cTrackerCfgParam.iRoadNumberBegin == 0)
                {
                    sprintf(szConf, "<左,%d>", m_cModuleParams.cTrackerCfgParam.iStartRoadNum);
                }
                else
                {
                    sprintf(szConf, "<右,%d>", m_cModuleParams.cTrackerCfgParam.iStartRoadNum);
                }
                pValue->SetAttribute("value", szConf);
                pValue->SetAttribute("chnname", "起始车道号");
                pResult->LinkEndChild(pValue);
            }

            //路口名称
            pValue = new TiXmlElement("StreetName");
            if (pValue)
            {
                pValue->SetAttribute("value", m_cModuleParams.cResultSenderParam.szStreetName);
                pValue->SetAttribute("chnname", "路口名称");
                pResult->LinkEndChild(pValue);
            }

            //路口方向
            pValue = new TiXmlElement("StreetDirection");
            if (pValue)
            {
                pValue->SetAttribute("value", m_cModuleParams.cResultSenderParam.szStreetDirection);
                pValue->SetAttribute("chnname", "路口方向");
                pResult->LinkEndChild(pValue);
            }

            //事件检测信息
            pValue = new TiXmlElement("EventCheck");
            if (pValue)
            {
                GetEventDetInfo(pCarLeftInfo, szConf);
                if (strlen(szConf) != 0)
                {
                    pValue->SetAttribute("value", szConf);
                    pValue->SetAttribute("chnname", "事件检测");
                    pResult->LinkEndChild(pValue);
                }
            }

            if (pCarLeftInfo->cCoreResult.cResultImg.pimgBestSnapShot)
            {
                //视频帧名
                strcpy(
                    szFrameName,
                    pCarLeftInfo->cCoreResult.cResultImg.pimgBestSnapShot->GetFrameName()
                );
                if (strlen(szFrameName) != 0
#ifdef SINGLE_BOARD_PLATFORM
                        && m_cModuleParams.cCamCfgParam.iCamType == 0 // 单板下0才是测试协议
#else
                        && m_cModuleParams.cCamCfgParam.iCamType == 1
#endif
                   )
                {
                    pValue = new TiXmlElement("FrameName");
                    if ( pValue )
                    {
                        char *pFirst = szFrameName, *pSecond = szFrameName;
                        char *pTemp = strstr(pFirst, ".");
                        while (pTemp)
                        {
                            pSecond = pTemp;
                            pTemp = strstr(pTemp + 1, ".");
                        }
                        szFrameName[pSecond - pFirst] = 0;
                        pValue->SetAttribute("value", szFrameName);
                        pValue->SetAttribute("chnname", "视频帧名");
                        pResult->LinkEndChild(pValue);
                    }
                }
            }

            //当前亮度级别
            pValue = new TiXmlElement("PlateLightType");
            if (pValue)
            {
                sprintf(szConf, "%02d级", pCarLeftInfo->cCoreResult.nPlateLightType);
                pValue->SetAttribute("value", szConf);
                pValue->SetAttribute("chnname", "摄像机亮度等级");
                pResult->LinkEndChild(pValue);
            }
            //} // end of if (m_cModuleParams.cResultSenderParam.fOutputAppendInfo)

#ifndef SINGLE_BOARD_PLATFORM
            //当前偏光镜状态
            pValue = new TiXmlElement("CplStatus");
            if (pValue)
            {
                sprintf(szConf, "%d", pCarLeftInfo->cCoreResult.iCplStatus);
                pValue->SetAttribute("value", szConf);
                pValue->SetAttribute("chnname", "偏光镜状态");
                pResult->LinkEndChild(pValue);
            }

            if (g_iControllPannelWorkStyle == 1)
            {
                //当前补光灯脉宽级别
                pValue = new TiXmlElement("PulseLevel");
                if (pValue)
                {
                    sprintf(szConf, "%d", pCarLeftInfo->cCoreResult.iPulseLevel);
                    pValue->SetAttribute("value", szConf);
                    pValue->SetAttribute("chnname", "补光脉宽等级");
                    pResult->LinkEndChild(pValue);
                }

                //补光灯状态判断
                static int iFillLightCount = 0;
                static int iFillLightMaxCount = (m_cModuleParams.cTrackerCfgParam.nPlateLightCheckCount << 1);
                if(iFillLightMaxCount < 20) iFillLightMaxCount = 20;
                int iMinAvgY = m_cModuleParams.cTrackerCfgParam.nMinPlateBrightness;
                if (pCarLeftInfo->cCoreResult.iPulseLevel > 0)
                {
                    if (pCarLeftInfo->cCoreResult.iCarAvgY < 50)
                    {
                        iFillLightCount++;
                    }
                    else
                    {
                        iFillLightCount = 0;
                    }
                    if (m_nLastLightLevel != pCarLeftInfo->cCoreResult.iPulseLevel)
                    {
                        iFillLightCount = 0;
                        m_nLastLightLevel = pCarLeftInfo->cCoreResult.iPulseLevel;
                    }
                    if (iFillLightCount > iFillLightMaxCount )
                    {
                        iFillLightCount = iFillLightMaxCount;
                        pValue = new TiXmlElement("FlashLightStatus");
                        if (pValue)
                        {
                            sprintf(szConf, "%s", "异常");
                            pValue->SetAttribute("value", szConf);
                            pValue->SetAttribute("chnname", "补光灯工作状态");
                            pResult->LinkEndChild(pValue);
                        }
                    }
                    else
                    {
                        pValue = new TiXmlElement("FlashLightStatus");
                        if (pValue)
                        {
                            sprintf(szConf, "%s", "正常");
                            pValue->SetAttribute("value", szConf);
                            pValue->SetAttribute("chnname", "补光灯工作状态");
                            pResult->LinkEndChild(pValue);
                        }
                    }
                }

                //闪光灯状态判断,无车牌时不进行判断
                static int iFlashLampCount = 0;
                if (pCarLeftInfo->cCoreResult.fIsCapture)
                {
                    if (pCarLeftInfo->cCoreResult.rgbContent[0] != 0)
                    {
                        if (pCarLeftInfo->cCoreResult.iPulseLevel > 0)
                        {
                            if (pCarLeftInfo->cCoreResult.iCapturerAvgY - pCarLeftInfo->cCoreResult.iAvgY
                                    < m_nFlashLampDiff)
                            {
                                iFlashLampCount++;
                            }
                            else
                            {
                                iFlashLampCount = 0;
                            }

                            if (iFlashLampCount > 5)
                            {
                                iFlashLampCount = 5;
                                pValue = new TiXmlElement("CaptureLightStatus");
                                if (pValue)
                                {
                                    sprintf(szConf, "%s", "异常");
                                    pValue->SetAttribute("value", szConf);
                                    pValue->SetAttribute("chnname", "闪光灯工作状态");
                                    pResult->LinkEndChild(pValue);
                                }
                            }
                            else
                            {
                                pValue = new TiXmlElement("CaptureLightStatus");
                                if (pValue)
                                {
                                    sprintf(szConf, "%s", "正常");
                                    pValue->SetAttribute("value", szConf);
                                    pValue->SetAttribute("chnname", "闪光灯工作状态");
                                    pResult->LinkEndChild(pValue);
                                }
                            }
                        }
                        else
                        {
                            iFlashLampCount = 0;
                        }
                    }
                }
                else
                {
                    if (pCarLeftInfo->cCoreResult.rgbContent[0] != 0)
                        iFlashLampCount = 0;
                }
            }
#endif

        } // end of if (m_cModuleParams.cResultSenderParam.fOutputAppendInfo)

        m_pLightTypeSaver->SaveLightType(
            pCarLeftInfo->cCoreResult.nPlateLightType,
            pCarLeftInfo->cCoreResult.iPulseLevel,
            pCarLeftInfo->cCoreResult.iCplStatus,
            pCarLeftInfo->cCoreResult.nCarArriveTime
        );

    } // end of if (pResult)

    TiXmlPrinter cTxPr;
    if (m_pXmlDoc)
    {
        cTxPr.SetStreamPrinting();
        m_pXmlDoc->Accept(&cTxPr);

        int nCpyLen = MIN_INT(*piPlateStringSize, (int)cTxPr.Size() + 1);
        HV_memcpy( pszPlateString, cTxPr.CStr(), nCpyLen );
        pszPlateString[nCpyLen - 1] = '\0';
        *piPlateStringSize = nCpyLen;
    }
    else
    {
        *piPlateStringSize = 0;
    }

    return S_OK;
}