130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/*
230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunwww.sourceforge.net/projects/tinyxml
330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunOriginal code by Lee Thomason (www.grinninglizard.com)
430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunThis software is provided 'as-is', without any express or implied
630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunwarranty. In no event will the authors be held liable for any
730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurundamages arising from the use of this software.
830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunPermission is granted to anyone to use this software for any
1030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunpurpose, including commercial applications, and to alter it and
1130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunredistribute it freely, subject to the following restrictions:
1230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
1330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun1. The origin of this software must not be misrepresented; you must
1430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnot claim that you wrote the original software. If you use this
1530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunsoftware in a product, an acknowledgment in the product documentation
1630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunwould be appreciated but is not required.
1730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun2. Altered source versions must be plainly marked as such, and
1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunmust not be misrepresented as being the original software.
2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun3. This notice may not be removed or altered from any source
2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurundistribution.
2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun*/
2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <ctype.h>
2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <stddef.h>
2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "tinyxml.h"
2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//#define DEBUG_PARSER
3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined( DEBUG_PARSER )
3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#	if defined( DEBUG ) && defined( _MSC_VER )
3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#		include <windows.h>
3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#		define TIXML_LOG OutputDebugString
3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#	else
3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#		define TIXML_LOG printf
3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#	endif
3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// Note tha "PutString" hardcodes the same list. This
4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// is less flexible than it appears. Changing the entries
4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// or order will break putstring.
4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunTiXmlBase::Entity TiXmlBase::entity[ TiXmlBase::NUM_ENTITY ] =
4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{ "&amp;",  5, '&' },
4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{ "&lt;",   4, '<' },
4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{ "&gt;",   4, '>' },
4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{ "&quot;", 6, '\"' },
4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{ "&apos;", 6, '\'' }
5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun};
5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// Bunch of unicode info at:
5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//		http://www.unicode.org/faq/utf_bom.html
5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// Including the basic of this table, which determines the #bytes in the
5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// sequence from the lead byte. 1 placed for invalid sequences --
5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// although the result will be junk, pass it through as much as possible.
5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// Beware of the non-characters in UTF-8:
5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//				ef bb bf (Microsoft "lead bytes")
5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//				ef bf be
6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//				ef bf bf
6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst unsigned char TIXML_UTF_LEAD_0 = 0xefU;
6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst int TiXmlBase::utf8ByteTable[256] =
6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	//	0	1	2	3	4	5	6	7	8	9	a	b	c	d	e	f
6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x00
7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x10
7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x20
7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x30
7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x40
7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x50
7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x60
7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x70	End of ASCII range
7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x80 0x80 to 0xc1 invalid
7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x90
7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xa0
8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xb0
8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		1,	1,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xc0 0xc2 to 0xdf 2 byte
8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xd0
8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	// 0xe0 0xe0 to 0xef 3 byte
8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		4,	4,	4,	4,	4,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1	// 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid
8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun};
8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length )
8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const unsigned long BYTE_MASK = 0xBF;
9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const unsigned long BYTE_MARK = 0x80;
9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if (input < 0x80)
9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		*length = 1;
9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else if ( input < 0x800 )
9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		*length = 2;
9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else if ( input < 0x10000 )
9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		*length = 3;
10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else if ( input < 0x200000 )
10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		*length = 4;
10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else
10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{ *length = 0; return; }	// This code won't covert this correctly anyway.
10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	output += *length;
10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Scary scary fall throughs.
10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	switch (*length)
10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		case 4:
11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			--output;
11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			*output = (char)((input | BYTE_MARK) & BYTE_MASK);
11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			input >>= 6;
11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		case 3:
11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			--output;
11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			*output = (char)((input | BYTE_MARK) & BYTE_MASK);
11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			input >>= 6;
11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		case 2:
11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			--output;
12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			*output = (char)((input | BYTE_MARK) & BYTE_MASK);
12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			input >>= 6;
12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		case 1:
12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			--output;
12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			*output = (char)(input | FIRST_BYTE_MARK[*length]);
12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// This will only work for low-ascii, everything else is assumed to be a valid
13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// letter. I'm not sure this is the best approach, but it is quite tricky trying
13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// to figure out alhabetical vs. not across encoding. So take a very
13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// conservative approach.
13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//	if ( encoding == TIXML_ENCODING_UTF8 )
13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//	{
13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( anyByte < 127 )
13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return isalpha( anyByte );
14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		else
14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return 1;	// What else to do? The unicode set is huge...get the english ones right.
14230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//	}
14330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//	else
14430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//	{
14530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//		return isalpha( anyByte );
14630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//	}
14730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
14830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
14930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
15030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
15130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
15230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// This will only work for low-ascii, everything else is assumed to be a valid
15330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// letter. I'm not sure this is the best approach, but it is quite tricky trying
15430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// to figure out alhabetical vs. not across encoding. So take a very
15530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// conservative approach.
15630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
15730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//	if ( encoding == TIXML_ENCODING_UTF8 )
15830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//	{
15930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( anyByte < 127 )
16030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return isalnum( anyByte );
16130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		else
16230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return 1;	// What else to do? The unicode set is huge...get the english ones right.
16330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//	}
16430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//	else
16530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//	{
16630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//		return isalnum( anyByte );
16730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//	}
16830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
16930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
17030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
17130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunclass TiXmlParsingData
17230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
17330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	friend class TiXmlDocument;
17430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  public:
17530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	void Stamp( const char* now, TiXmlEncoding encoding );
17630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
17730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const TiXmlCursor& Cursor() const	{ return cursor; }
17830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
17930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  private:
18030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Only used by the document!
18130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	TiXmlParsingData( const char* start, int _tabsize, int row, int col )
18230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
18330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		assert( start );
18430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		stamp = start;
18530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		tabsize = _tabsize;
18630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		cursor.row = row;
18730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		cursor.col = col;
18830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
18930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
19030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	TiXmlCursor		cursor;
19130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char*		stamp;
19230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	int				tabsize;
19330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun};
19430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
19530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
19630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding )
19730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
19830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	assert( now );
19930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
20030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Do nothing if the tabsize is 0.
20130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( tabsize < 1 )
20230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
20330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return;
20430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
20530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
20630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Get the current row, column.
20730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	int row = cursor.row;
20830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	int col = cursor.col;
20930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char* p = stamp;
21030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	assert( p );
21130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
21230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	while ( p < now )
21330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
21430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		// Treat p as unsigned, so we have a happy compiler.
21530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		const unsigned char* pU = (const unsigned char*)p;
21630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
21730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		// Code contributed by Fletcher Dunn: (modified by lee)
21830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		switch (*pU) {
21930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			case 0:
22030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// We *should* never get here, but in case we do, don't
22130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// advance past the terminating null character, ever
22230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				return;
22330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
22430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			case '\r':
22530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// bump down to the next line
22630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				++row;
22730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				col = 0;
22830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// Eat the character
22930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				++p;
23030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
23130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// Check for \r\n sequence, and treat this as a single character
23230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if (*p == '\n') {
23330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					++p;
23430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				}
23530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				break;
23630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
23730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			case '\n':
23830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// bump down to the next line
23930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				++row;
24030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				col = 0;
24130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
24230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// Eat the character
24330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				++p;
24430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
24530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// Check for \n\r sequence, and treat this as a single
24630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// character.  (Yes, this bizarre thing does occur still
24730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// on some arcane platforms...)
24830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if (*p == '\r') {
24930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					++p;
25030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				}
25130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				break;
25230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
25330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			case '\t':
25430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// Eat the character
25530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				++p;
25630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
25730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// Skip to next tab stop
25830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				col = (col / tabsize + 1) * tabsize;
25930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				break;
26030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
26130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			case TIXML_UTF_LEAD_0:
26230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( encoding == TIXML_ENCODING_UTF8 )
26330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				{
26430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					if ( *(p+1) && *(p+2) )
26530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					{
26630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun						// In these cases, don't advance the column. These are
26730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun						// 0-width spaces.
26830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun						if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 )
26930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun							p += 3;
27030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
27130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun							p += 3;
27230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
27330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun							p += 3;
27430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun						else
27530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun							{ p +=3; ++col; }	// A normal character.
27630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					}
27730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				}
27830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				else
27930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				{
28030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					++p;
28130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					++col;
28230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				}
28330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				break;
28430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
28530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			default:
28630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( encoding == TIXML_ENCODING_UTF8 )
28730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				{
28830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					// Eat the 1 to 4 byte utf8 character.
28930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)];
29030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					if ( step == 0 )
29130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun						step = 1;		// Error case from bad encoding, but handle gracefully.
29230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					p += step;
29330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
29430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					// Just advance one column, of course.
29530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					++col;
29630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				}
29730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				else
29830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				{
29930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					++p;
30030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					++col;
30130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				}
30230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				break;
30330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
30430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
30530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	cursor.row = row;
30630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	cursor.col = col;
30730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	assert( cursor.row >= -1 );
30830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	assert( cursor.col >= -1 );
30930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	stamp = p;
31030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	assert( stamp );
31130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
31230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
31330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
31430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
31530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
31630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !p || !*p )
31730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
31830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return 0;
31930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
32030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( encoding == TIXML_ENCODING_UTF8 )
32130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
32230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		while ( *p )
32330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
32430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			const unsigned char* pU = (const unsigned char*)p;
32530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
32630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// Skip the stupid Microsoft UTF-8 Byte order marks
32730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if (	*(pU+0)==TIXML_UTF_LEAD_0
32830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				 && *(pU+1)==TIXML_UTF_LEAD_1
32930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				 && *(pU+2)==TIXML_UTF_LEAD_2 )
33030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
33130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				p += 3;
33230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				continue;
33330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
33430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			else if(*(pU+0)==TIXML_UTF_LEAD_0
33530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				 && *(pU+1)==0xbfU
33630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				 && *(pU+2)==0xbeU )
33730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
33830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				p += 3;
33930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				continue;
34030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
34130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			else if(*(pU+0)==TIXML_UTF_LEAD_0
34230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				 && *(pU+1)==0xbfU
34330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				 && *(pU+2)==0xbfU )
34430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
34530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				p += 3;
34630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				continue;
34730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
34830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
34930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( IsWhiteSpace( *p ) )		// Still using old rules for white space.
35030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				++p;
35130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			else
35230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				break;
35330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
35430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
35530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else
35630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
35730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		while ( *p && IsWhiteSpace( *p ) )
35830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			++p;
35930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
36030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
36130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	return p;
36230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
36330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
36430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifdef TIXML_USE_STL
36530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag )
36630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
36730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	for( ;; )
36830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
36930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( !in->good() ) return false;
37030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
37130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		int c = in->peek();
37230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		// At this scope, we can't get to a document. So fail silently.
37330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( !IsWhiteSpace( c ) || c <= 0 )
37430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return true;
37530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
37630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		*tag += (char) in->get();
37730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
37830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
37930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
38030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag )
38130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
38230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	//assert( character > 0 && character < 128 );	// else it won't work in utf-8
38330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	while ( in->good() )
38430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
38530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		int c = in->peek();
38630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( c == character )
38730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return true;
38830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( c <= 0 )		// Silent failure: can't get document at this scope
38930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return false;
39030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
39130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		in->get();
39230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		*tag += (char) c;
39330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
39430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	return false;
39530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
39630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
39730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
39830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The
39930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// "assign" optimization removes over 10% of the execution time.
40030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun//
40130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding )
40230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
40330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Oddly, not supported on some comilers,
40430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	//name->clear();
40530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// So use this:
40630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	*name = "";
40730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	assert( p );
40830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
40930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Names start with letters or underscores.
41030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Of course, in unicode, tinyxml has no idea what a letter *is*. The
41130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// algorithm is generous.
41230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	//
41330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// After that, they can be letters, underscores, numbers,
41430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// hyphens, or colons. (Colons are valid ony for namespaces,
41530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// but tinyxml can't tell namespaces from names.)
41630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if (    p && *p
41730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		 && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
41830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
41930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		const char* start = p;
42030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		while(		p && *p
42130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				&&	(		IsAlphaNum( (unsigned char ) *p, encoding )
42230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun						 || *p == '_'
42330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun						 || *p == '-'
42430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun						 || *p == '.'
42530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun						 || *p == ':' ) )
42630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
42730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			//(*name) += *p; // expensive
42830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			++p;
42930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
43030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( p-start > 0 ) {
43130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			name->assign( start, p-start );
43230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
43330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return p;
43430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
43530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	return 0;
43630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
43730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
43830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding )
43930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
44030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Presume an entity, and pull it out.
44130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    TIXML_STRING ent;
44230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	int i;
44330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	*length = 0;
44430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
44530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( *(p+1) && *(p+1) == '#' && *(p+2) )
44630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
44730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		unsigned long ucs = 0;
44830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		ptrdiff_t delta = 0;
44930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		unsigned mult = 1;
45030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
45130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( *(p+2) == 'x' )
45230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
45330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// Hexadecimal.
45430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( !*(p+3) ) return 0;
45530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
45630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			const char* q = p+3;
45730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			q = strchr( q, ';' );
45830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
45930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( !q || !*q ) return 0;
46030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
46130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			delta = q-p;
46230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			--q;
46330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
46430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			while ( *q != 'x' )
46530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
46630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( *q >= '0' && *q <= '9' )
46730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					ucs += mult * (*q - '0');
46830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				else if ( *q >= 'a' && *q <= 'f' )
46930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					ucs += mult * (*q - 'a' + 10);
47030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				else if ( *q >= 'A' && *q <= 'F' )
47130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					ucs += mult * (*q - 'A' + 10 );
47230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				else
47330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					return 0;
47430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				mult *= 16;
47530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				--q;
47630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
47730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
47830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		else
47930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
48030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// Decimal.
48130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( !*(p+2) ) return 0;
48230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
48330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			const char* q = p+2;
48430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			q = strchr( q, ';' );
48530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
48630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( !q || !*q ) return 0;
48730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
48830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			delta = q-p;
48930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			--q;
49030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
49130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			while ( *q != '#' )
49230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
49330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( *q >= '0' && *q <= '9' )
49430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					ucs += mult * (*q - '0');
49530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				else
49630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					return 0;
49730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				mult *= 10;
49830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				--q;
49930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
50030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
50130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( encoding == TIXML_ENCODING_UTF8 )
50230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
50330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// convert the UCS to UTF-8
50430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			ConvertUTF32ToUTF8( ucs, value, length );
50530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
50630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		else
50730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
50830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			*value = (char)ucs;
50930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			*length = 1;
51030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
51130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return p + delta + 1;
51230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
51330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
51430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Now try to match it.
51530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	for( i=0; i<NUM_ENTITY; ++i )
51630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
51730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 )
51830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
51930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			assert( strlen( entity[i].str ) == entity[i].strLength );
52030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			*value = entity[i].chr;
52130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			*length = 1;
52230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return ( p + entity[i].strLength );
52330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
52430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
52530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
52630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// So it wasn't an entity, its unrecognized, or something like that.
52730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	*value = *p;	// Don't put back the last one, since we return it!
52830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	//*length = 1;	// Leave unrecognized entities - this doesn't really work.
52930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					// Just writes strange XML.
53030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	return p+1;
53130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
53230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
53330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
53430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool TiXmlBase::StringEqual( const char* p,
53530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun							 const char* tag,
53630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun							 bool ignoreCase,
53730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun							 TiXmlEncoding encoding )
53830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
53930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	assert( p );
54030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	assert( tag );
54130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !p || !*p )
54230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
54330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		assert( 0 );
54430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return false;
54530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
54630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
54730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char* q = p;
54830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
54930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( ignoreCase )
55030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
55130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		while ( *q && *tag && ToLower( *q, encoding ) == ToLower( *tag, encoding ) )
55230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
55330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			++q;
55430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			++tag;
55530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
55630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
55730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( *tag == 0 )
55830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return true;
55930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
56030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else
56130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
56230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		while ( *q && *tag && *q == *tag )
56330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
56430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			++q;
56530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			++tag;
56630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
56730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
56830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( *tag == 0 )		// Have we found the end of the tag, and everything equal?
56930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return true;
57030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
57130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	return false;
57230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
57330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
57430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst char* TiXmlBase::ReadText(	const char* p,
57530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun									TIXML_STRING * text,
57630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun									bool trimWhiteSpace,
57730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun									const char* endTag,
57830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun									bool caseInsensitive,
57930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun									TiXmlEncoding encoding )
58030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
58130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    *text = "";
58230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if (    !trimWhiteSpace			// certain tags always keep whitespace
58330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		 || !condenseWhiteSpace )	// if true, whitespace is always kept
58430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
58530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		// Keep all the white space.
58630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		while (	   p && *p
58730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				&& !StringEqual( p, endTag, caseInsensitive, encoding )
58830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			  )
58930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
59030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			int len;
59130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			char cArr[4] = { 0, 0, 0, 0 };
59230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			p = GetChar( p, cArr, &len, encoding );
59330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			text->append( cArr, len );
59430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
59530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
59630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else
59730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
59830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		bool whitespace = false;
59930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
60030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		// Remove leading white space:
60130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		p = SkipWhiteSpace( p, encoding );
60230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		while (	   p && *p
60330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				&& !StringEqual( p, endTag, caseInsensitive, encoding ) )
60430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
60530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( *p == '\r' || *p == '\n' )
60630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
60730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				whitespace = true;
60830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				++p;
60930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
61030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			else if ( IsWhiteSpace( *p ) )
61130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
61230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				whitespace = true;
61330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				++p;
61430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
61530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			else
61630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
61730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// If we've found whitespace, add it before the
61830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// new character. Any whitespace just becomes a space.
61930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( whitespace )
62030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				{
62130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					(*text) += ' ';
62230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					whitespace = false;
62330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				}
62430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				int len;
62530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				char cArr[4] = { 0, 0, 0, 0 };
62630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				p = GetChar( p, cArr, &len, encoding );
62730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( len == 1 )
62830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					(*text) += cArr[0];	// more efficient
62930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				else
63030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					text->append( cArr, len );
63130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
63230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
63330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
63430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( p && *p )
63530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		p += strlen( endTag );
63630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	return ( p && *p ) ? p : 0;
63730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
63830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
63930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifdef TIXML_USE_STL
64030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
64130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag )
64230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
64330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// The basic issue with a document is that we don't know what we're
64430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// streaming. Read something presumed to be a tag (and hope), then
64530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// identify it, and call the appropriate stream method on the tag.
64630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	//
64730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// This "pre-streaming" will never read the closing ">" so the
64830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// sub-tag can orient itself.
64930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
65030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !StreamTo( in, '<', tag ) )
65130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
65230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
65330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return;
65430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
65530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
65630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	while ( in->good() )
65730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
65830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		int tagIndex = (int) tag->length();
65930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		while ( in->good() && in->peek() != '>' )
66030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
66130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			int c = in->get();
66230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( c <= 0 )
66330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
66430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
66530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				break;
66630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
66730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			(*tag) += (char) c;
66830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
66930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
67030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( in->good() )
67130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
67230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// We now have something we presume to be a node of
67330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// some sort. Identify it, and call the node to
67430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// continue streaming.
67530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING );
67630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
67730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( node )
67830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
67930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				node->StreamIn( in, tag );
68030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				bool isElement = node->ToElement() != 0;
68130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				delete node;
68230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				node = 0;
68330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
68430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// If this is the root element, we're done. Parsing will be
68530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// done by the >> operator.
68630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( isElement )
68730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				{
68830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					return;
68930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				}
69030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
69130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			else
69230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
69330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
69430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				return;
69530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
69630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
69730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
69830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// We should have returned sooner.
69930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
70030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
70130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
70230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
70330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
70430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding )
70530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
70630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	ClearError();
70730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
70830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Parse away, at the document level. Since a document
70930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// contains nothing but other tags, most of what happens
71030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// here is skipping white space.
71130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !p || !*p )
71230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
71330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
71430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return 0;
71530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
71630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
71730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Note that, for a document, this needs to come
71830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// before the while space skip, so that parsing
71930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// starts from the pointer we are given.
72030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	location.Clear();
72130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( prevData )
72230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
72330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		location.row = prevData->cursor.row;
72430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		location.col = prevData->cursor.col;
72530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
72630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else
72730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
72830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		location.row = 0;
72930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		location.col = 0;
73030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
73130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	TiXmlParsingData data( p, TabSize(), location.row, location.col );
73230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	location = data.Cursor();
73330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
73430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( encoding == TIXML_ENCODING_UNKNOWN )
73530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
73630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		// Check for the Microsoft UTF-8 lead bytes.
73730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		const unsigned char* pU = (const unsigned char*)p;
73830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if (	*(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0
73930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			 && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1
74030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			 && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 )
74130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
74230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			encoding = TIXML_ENCODING_UTF8;
74330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			useMicrosoftBOM = true;
74430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
74530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
74630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
74730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    p = SkipWhiteSpace( p, encoding );
74830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !p )
74930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
75030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
75130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return 0;
75230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
75330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
75430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	while ( p && *p )
75530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
75630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		TiXmlNode* node = Identify( p, encoding );
75730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( node )
75830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
75930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			p = node->Parse( p, &data, encoding );
76030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			LinkEndChild( node );
76130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
76230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		else
76330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
76430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			break;
76530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
76630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
76730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		// Did we get encoding info?
76830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if (    encoding == TIXML_ENCODING_UNKNOWN
76930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			 && node->ToDeclaration() )
77030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
77130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TiXmlDeclaration* dec = node->ToDeclaration();
77230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			const char* enc = dec->Encoding();
77330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			assert( enc );
77430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
77530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( *enc == 0 )
77630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				encoding = TIXML_ENCODING_UTF8;
77730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) )
77830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				encoding = TIXML_ENCODING_UTF8;
77930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) )
78030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				encoding = TIXML_ENCODING_UTF8;	// incorrect, but be nice
78130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			else
78230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				encoding = TIXML_ENCODING_LEGACY;
78330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
78430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
78530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		p = SkipWhiteSpace( p, encoding );
78630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
78730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
78830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Was this empty?
78930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !firstChild ) {
79030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding );
79130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return 0;
79230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
79330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
79430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// All is well.
79530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	return p;
79630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
79730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
79830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding )
79930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
80030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// The first error in a chain is more accurate - don't set again!
80130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( error )
80230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return;
80330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
80430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
80530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	error   = true;
80630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	errorId = err;
80730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	errorDesc = errorString[ errorId ];
80830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
80930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	errorLocation.Clear();
81030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( pError && data )
81130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
81230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		data->Stamp( pError, encoding );
81330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		errorLocation = data->Cursor();
81430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
81530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
81630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
81730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
81830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunTiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
81930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
82030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	TiXmlNode* returnNode = 0;
82130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
82230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	p = SkipWhiteSpace( p, encoding );
82330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if( !p || !*p || *p != '<' )
82430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
82530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return 0;
82630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
82730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
82830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	p = SkipWhiteSpace( p, encoding );
82930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
83030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !p || !*p )
83130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
83230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return 0;
83330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
83430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
83530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// What is this thing?
83630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// - Elements start with a letter or underscore, but xml is reserved.
83730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// - Comments: <!--
83830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// - Decleration: <?xml
83930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// - Everthing else is unknown to tinyxml.
84030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	//
84130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
84230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char* xmlHeader = { "<?xml" };
84330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char* commentHeader = { "<!--" };
84430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char* dtdHeader = { "<!" };
84530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char* cdataHeader = { "<![CDATA[" };
84630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
84730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( StringEqual( p, xmlHeader, true, encoding ) )
84830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
84930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		#ifdef DEBUG_PARSER
85030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TIXML_LOG( "XML parsing Declaration\n" );
85130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		#endif
85230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		returnNode = new TiXmlDeclaration();
85330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
85430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else if ( StringEqual( p, commentHeader, false, encoding ) )
85530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
85630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		#ifdef DEBUG_PARSER
85730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TIXML_LOG( "XML parsing Comment\n" );
85830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		#endif
85930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		returnNode = new TiXmlComment();
86030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
86130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else if ( StringEqual( p, cdataHeader, false, encoding ) )
86230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
86330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		#ifdef DEBUG_PARSER
86430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TIXML_LOG( "XML parsing CDATA\n" );
86530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		#endif
86630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		TiXmlText* text = new TiXmlText( "" );
86730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		text->SetCDATA( true );
86830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		returnNode = text;
86930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
87030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else if ( StringEqual( p, dtdHeader, false, encoding ) )
87130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
87230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		#ifdef DEBUG_PARSER
87330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TIXML_LOG( "XML parsing Unknown(1)\n" );
87430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		#endif
87530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		returnNode = new TiXmlUnknown();
87630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
87730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else if (    IsAlpha( *(p+1), encoding )
87830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			  || *(p+1) == '_' )
87930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
88030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		#ifdef DEBUG_PARSER
88130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TIXML_LOG( "XML parsing Element\n" );
88230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		#endif
88330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		returnNode = new TiXmlElement( "" );
88430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
88530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else
88630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
88730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		#ifdef DEBUG_PARSER
88830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TIXML_LOG( "XML parsing Unknown(2)\n" );
88930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		#endif
89030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		returnNode = new TiXmlUnknown();
89130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
89230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
89330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( returnNode )
89430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
89530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		// Set the parent, so it can report errors
89630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		returnNode->parent = this;
89730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
89830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	return returnNode;
89930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
90030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
90130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifdef TIXML_USE_STL
90230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
90330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag)
90430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
90530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// We're called with some amount of pre-parsing. That is, some of "this"
90630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// element is in "tag". Go ahead and stream to the closing ">"
90730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	while( in->good() )
90830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
90930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		int c = in->get();
91030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( c <= 0 )
91130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
91230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TiXmlDocument* document = GetDocument();
91330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( document )
91430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
91530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return;
91630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
91730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		(*tag) += (char) c ;
91830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
91930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( c == '>' )
92030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			break;
92130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
92230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
92330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( tag->length() < 3 ) return;
92430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
92530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Okay...if we are a "/>" tag, then we're done. We've read a complete tag.
92630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// If not, identify and stream.
92730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
92830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if (    tag->at( tag->length() - 1 ) == '>'
92930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		 && tag->at( tag->length() - 2 ) == '/' )
93030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
93130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		// All good!
93230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return;
93330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
93430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else if ( tag->at( tag->length() - 1 ) == '>' )
93530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
93630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		// There is more. Could be:
93730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		//		text
93830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		//		cdata text (which looks like another node)
93930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		//		closing tag
94030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		//		another node.
94130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		for ( ;; )
94230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
94330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			StreamWhiteSpace( in, tag );
94430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
94530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// Do we have text?
94630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( in->good() && in->peek() != '<' )
94730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
94830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// Yep, text.
94930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				TiXmlText text( "" );
95030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				text.StreamIn( in, tag );
95130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
95230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// What follows text is a closing tag or another node.
95330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// Go around again and figure it out.
95430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				continue;
95530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
95630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
95730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// We now have either a closing tag...or another node.
95830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// We should be at a "<", regardless.
95930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( !in->good() ) return;
96030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			assert( in->peek() == '<' );
96130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			int tagIndex = (int) tag->length();
96230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
96330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			bool closingTag = false;
96430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			bool firstCharFound = false;
96530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
96630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			for( ;; )
96730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
96830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( !in->good() )
96930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					return;
97030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
97130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				int c = in->peek();
97230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( c <= 0 )
97330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				{
97430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					TiXmlDocument* document = GetDocument();
97530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					if ( document )
97630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
97730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					return;
97830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				}
97930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
98030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( c == '>' )
98130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					break;
98230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
98330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				*tag += (char) c;
98430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				in->get();
98530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
98630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// Early out if we find the CDATA id.
98730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( c == '[' && tag->size() >= 9 )
98830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				{
98930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					size_t len = tag->size();
99030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					const char* start = tag->c_str() + len - 9;
99130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					if ( strcmp( start, "<![CDATA[" ) == 0 ) {
99230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun						assert( !closingTag );
99330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun						break;
99430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					}
99530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				}
99630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
99730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) )
99830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				{
99930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					firstCharFound = true;
100030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					if ( c == '/' )
100130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun						closingTag = true;
100230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				}
100330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
100430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// If it was a closing tag, then read in the closing '>' to clean up the input stream.
100530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// If it was not, the streaming will be done by the tag.
100630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( closingTag )
100730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
100830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( !in->good() )
100930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					return;
101030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
101130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				int c = in->get();
101230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( c <= 0 )
101330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				{
101430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					TiXmlDocument* document = GetDocument();
101530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					if ( document )
101630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
101730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					return;
101830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				}
101930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				assert( c == '>' );
102030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				*tag += (char) c;
102130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
102230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// We are done, once we've found our closing tag.
102330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				return;
102430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
102530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			else
102630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
102730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// If not a closing tag, id it, and stream.
102830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				const char* tagloc = tag->c_str() + tagIndex;
102930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				TiXmlNode* node = Identify( tagloc, TIXML_DEFAULT_ENCODING );
103030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( !node )
103130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					return;
103230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				node->StreamIn( in, tag );
103330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				delete node;
103430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				node = 0;
103530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
103630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// No return: go around from the beginning: text, closing tag, or node.
103730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
103830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
103930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
104030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
104130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
104230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
104330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
104430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
104530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	p = SkipWhiteSpace( p, encoding );
104630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	TiXmlDocument* document = GetDocument();
104730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
104830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !p || !*p )
104930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
105030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding );
105130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return 0;
105230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
105330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
105430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( data )
105530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
105630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		data->Stamp( p, encoding );
105730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		location = data->Cursor();
105830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
105930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
106030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( *p != '<' )
106130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
106230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding );
106330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return 0;
106430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
106530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
106630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	p = SkipWhiteSpace( p+1, encoding );
106730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
106830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Read the name.
106930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char* pErr = p;
107030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
107130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    p = ReadName( p, &value, encoding );
107230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !p || !*p )
107330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
107430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( document )	document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding );
107530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return 0;
107630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
107730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
107830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    TIXML_STRING endTag ("</");
107930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	endTag += value;
108030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
108130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Check for and read attributes. Also look for an empty
108230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// tag or an end tag.
108330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	while ( p && *p )
108430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
108530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		pErr = p;
108630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		p = SkipWhiteSpace( p, encoding );
108730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( !p || !*p )
108830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
108930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
109030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return 0;
109130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
109230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( *p == '/' )
109330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
109430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			++p;
109530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// Empty tag.
109630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( *p  != '>' )
109730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
109830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );
109930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				return 0;
110030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
110130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return (p+1);
110230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
110330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		else if ( *p == '>' )
110430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
110530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// Done with attributes (if there were any.)
110630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// Read the value -- which can include other
110730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// elements -- read the end tag, and return.
110830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			++p;
110930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			p = ReadValue( p, data, encoding );		// Note this is an Element method, and will set the error if one happens.
111030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( !p || !*p ) {
111130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// We were looking for the end tag, but found nothing.
111230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// Fix for [ 1663758 ] Failure to report error on bad XML
111330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
111430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				return 0;
111530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
111630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
111730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// We should find the end tag now
111830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// note that:
111930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// </foo > and
112030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// </foo>
112130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// are both valid end tags.
112230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( StringEqual( p, endTag.c_str(), false, encoding ) )
112330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
112430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				p += endTag.length();
112530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				p = SkipWhiteSpace( p, encoding );
112630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( p && *p && *p == '>' ) {
112730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					++p;
112830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					return p;
112930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				}
113030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
113130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				return 0;
113230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
113330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			else
113430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
113530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
113630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				return 0;
113730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
113830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
113930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		else
114030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
114130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// Try to read an attribute:
114230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TiXmlAttribute* attrib = new TiXmlAttribute();
114330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( !attrib )
114430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
114530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				return 0;
114630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
114730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
114830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			attrib->SetDocument( document );
114930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			pErr = p;
115030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			p = attrib->Parse( p, data, encoding );
115130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
115230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( !p || !*p )
115330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
115430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
115530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				delete attrib;
115630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				return 0;
115730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
115830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
115930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// Handle the strange case of double attributes:
116030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			#ifdef TIXML_USE_STL
116130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TiXmlAttribute* node = attributeSet.Find( attrib->NameTStr() );
116230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			#else
116330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TiXmlAttribute* node = attributeSet.Find( attrib->Name() );
116430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			#endif
116530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( node )
116630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
116730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
116830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				delete attrib;
116930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				return 0;
117030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
117130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
117230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			attributeSet.Add( attrib );
117330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
117430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
117530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	return p;
117630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
117730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
117830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
117930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
118030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
118130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	TiXmlDocument* document = GetDocument();
118230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
118330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Read in text and elements in any order.
118430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char* pWithWhiteSpace = p;
118530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	p = SkipWhiteSpace( p, encoding );
118630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
118730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	while ( p && *p )
118830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
118930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( *p != '<' )
119030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
119130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// Take what we have, make a text element.
119230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TiXmlText* textNode = new TiXmlText( "" );
119330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
119430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( !textNode )
119530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
119630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			    return 0;
119730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
119830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
119930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( TiXmlBase::IsWhiteSpaceCondensed() )
120030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
120130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				p = textNode->Parse( p, data, encoding );
120230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
120330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			else
120430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
120530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// Special case: we want to keep the white space
120630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// so that leading spaces aren't removed.
120730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				p = textNode->Parse( pWithWhiteSpace, data, encoding );
120830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
120930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
121030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( !textNode->Blank() )
121130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				LinkEndChild( textNode );
121230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			else
121330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				delete textNode;
121430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
121530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		else
121630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
121730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// We hit a '<'
121830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// Have we hit a new element or an end tag? This could also be
121930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// a TiXmlText in the "CDATA" style.
122030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( StringEqual( p, "</", false, encoding ) )
122130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
122230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				return p;
122330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
122430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			else
122530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			{
122630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				TiXmlNode* node = Identify( p, encoding );
122730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( node )
122830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				{
122930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					p = node->Parse( p, data, encoding );
123030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					LinkEndChild( node );
123130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				}
123230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				else
123330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				{
123430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun					return 0;
123530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				}
123630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
123730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
123830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		pWithWhiteSpace = p;
123930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		p = SkipWhiteSpace( p, encoding );
124030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
124130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
124230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !p )
124330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
124430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding );
124530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
124630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	return p;
124730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
124830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
124930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
125030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifdef TIXML_USE_STL
125130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid TiXmlUnknown::StreamIn( std::istream * in, TIXML_STRING * tag )
125230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
125330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	while ( in->good() )
125430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
125530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		int c = in->get();
125630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( c <= 0 )
125730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
125830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TiXmlDocument* document = GetDocument();
125930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( document )
126030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
126130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return;
126230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
126330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		(*tag) += (char) c;
126430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
126530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( c == '>' )
126630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
126730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// All is well.
126830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return;
126930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
127030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
127130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
127230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
127330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
127430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
127530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
127630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
127730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	TiXmlDocument* document = GetDocument();
127830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	p = SkipWhiteSpace( p, encoding );
127930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
128030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( data )
128130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
128230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		data->Stamp( p, encoding );
128330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		location = data->Cursor();
128430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
128530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !p || !*p || *p != '<' )
128630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
128730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, p, data, encoding );
128830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return 0;
128930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
129030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	++p;
129130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    value = "";
129230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
129330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	while ( p && *p && *p != '>' )
129430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
129530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		value += *p;
129630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		++p;
129730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
129830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
129930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !p )
130030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
130130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( document )
130230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding );
130330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
130430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( p && *p == '>' )
130530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return p+1;
130630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	return p;
130730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
130830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
130930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifdef TIXML_USE_STL
131030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid TiXmlComment::StreamIn( std::istream * in, TIXML_STRING * tag )
131130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
131230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	while ( in->good() )
131330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
131430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		int c = in->get();
131530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( c <= 0 )
131630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
131730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TiXmlDocument* document = GetDocument();
131830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( document )
131930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
132030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return;
132130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
132230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
132330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		(*tag) += (char) c;
132430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
132530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( c == '>'
132630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			 && tag->at( tag->length() - 2 ) == '-'
132730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			 && tag->at( tag->length() - 3 ) == '-' )
132830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
132930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// All is well.
133030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return;
133130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
133230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
133330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
133430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
133530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
133630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
133730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
133830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
133930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	TiXmlDocument* document = GetDocument();
134030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	value = "";
134130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
134230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	p = SkipWhiteSpace( p, encoding );
134330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
134430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( data )
134530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
134630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		data->Stamp( p, encoding );
134730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		location = data->Cursor();
134830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
134930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char* startTag = "<!--";
135030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char* endTag   = "-->";
135130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
135230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !StringEqual( p, startTag, false, encoding ) )
135330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
135430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( document )
135530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding );
135630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return 0;
135730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
135830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	p += strlen( startTag );
135930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
136030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// [ 1475201 ] TinyXML parses entities in comments
136130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Oops - ReadText doesn't work, because we don't want to parse the entities.
136230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// p = ReadText( p, &value, false, endTag, false, encoding );
136330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	//
136430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// from the XML spec:
136530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	/*
136630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	 [Definition: Comments may appear anywhere in a document outside other markup; in addition,
136730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	              they may appear within the document type declaration at places allowed by the grammar.
136830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				  They are not part of the document's character data; an XML processor MAY, but need not,
136930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				  make it possible for an application to retrieve the text of comments. For compatibility,
137030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				  the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity
137130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				  references MUST NOT be recognized within comments.
137230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
137330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				  An example of a comment:
137430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
137530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				  <!-- declarations for <head> & <body> -->
137630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	*/
137730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
137830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    value = "";
137930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Keep all the white space.
138030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	while (	p && *p && !StringEqual( p, endTag, false, encoding ) )
138130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
138230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		value.append( p, 1 );
138330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		++p;
138430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
138530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( p && *p )
138630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		p += strlen( endTag );
138730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
138830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	return p;
138930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
139030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
139130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
139230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
139330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
139430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	p = SkipWhiteSpace( p, encoding );
139530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !p || !*p ) return 0;
139630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
139730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( data )
139830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
139930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		data->Stamp( p, encoding );
140030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		location = data->Cursor();
140130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
140230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Read the name, the '=' and the value.
140330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char* pErr = p;
140430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	p = ReadName( p, &name, encoding );
140530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !p || !*p )
140630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
140730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
140830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return 0;
140930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
141030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	p = SkipWhiteSpace( p, encoding );
141130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !p || !*p || *p != '=' )
141230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
141330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
141430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return 0;
141530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
141630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
141730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	++p;	// skip '='
141830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	p = SkipWhiteSpace( p, encoding );
141930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !p || !*p )
142030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
142130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
142230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return 0;
142330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
142430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
142530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char* end;
142630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char SINGLE_QUOTE = '\'';
142730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char DOUBLE_QUOTE = '\"';
142830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
142930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( *p == SINGLE_QUOTE )
143030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
143130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		++p;
143230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		end = "\'";		// single quote in string
143330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		p = ReadText( p, &value, false, end, false, encoding );
143430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
143530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else if ( *p == DOUBLE_QUOTE )
143630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
143730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		++p;
143830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		end = "\"";		// double quote in string
143930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		p = ReadText( p, &value, false, end, false, encoding );
144030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
144130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else
144230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
144330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		// All attribute values should be in single or double quotes.
144430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		// But this is such a common error that the parser will try
144530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		// its best, even without them.
144630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		value = "";
144730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		while (    p && *p											// existence
144830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				&& !IsWhiteSpace( *p )								// whitespace
144930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				&& *p != '/' && *p != '>' )							// tag end
145030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
145130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) {
145230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// [ 1451649 ] Attribute values with trailing quotes not handled correctly
145330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// We did not have an opening quote but seem to have a
145430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// closing one. Give up and throw an error.
145530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
145630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				return 0;
145730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
145830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			value += *p;
145930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			++p;
146030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
146130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
146230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	return p;
146330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
146430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
146530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifdef TIXML_USE_STL
146630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag )
146730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
146830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	while ( in->good() )
146930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
147030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		int c = in->peek();
147130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( !cdata && (c == '<' ) )
147230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
147330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return;
147430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
147530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( c <= 0 )
147630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
147730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TiXmlDocument* document = GetDocument();
147830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( document )
147930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
148030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return;
148130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
148230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
148330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		(*tag) += (char) c;
148430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		in->get();	// "commits" the peek made above
148530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
148630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( cdata && c == '>' && tag->size() >= 3 ) {
148730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			size_t len = tag->size();
148830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) {
148930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				// terminator of cdata.
149030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				return;
149130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			}
149230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
149330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
149430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
149530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
149630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
149730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
149830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
149930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	value = "";
150030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	TiXmlDocument* document = GetDocument();
150130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
150230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( data )
150330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
150430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		data->Stamp( p, encoding );
150530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		location = data->Cursor();
150630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
150730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
150830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char* const startTag = "<![CDATA[";
150930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	const char* const endTag   = "]]>";
151030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
151130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( cdata || StringEqual( p, startTag, false, encoding ) )
151230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
151330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		cdata = true;
151430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
151530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( !StringEqual( p, startTag, false, encoding ) )
151630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
151730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( document )
151830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding );
151930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return 0;
152030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
152130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		p += strlen( startTag );
152230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
152330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		// Keep all the white space, ignore the encoding, etc.
152430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		while (	   p && *p
152530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				&& !StringEqual( p, endTag, false, encoding )
152630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			  )
152730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
152830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			value += *p;
152930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			++p;
153030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
153130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
153230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		TIXML_STRING dummy;
153330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		p = ReadText( p, &dummy, false, endTag, false, encoding );
153430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return p;
153530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
153630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	else
153730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
153830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		bool ignoreWhite = true;
153930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
154030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		const char* end = "<";
154130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		p = ReadText( p, &value, ignoreWhite, end, false, encoding );
154230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( p && *p )
154330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return p-1;	// don't truncate the '<'
154430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return 0;
154530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
154630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
154730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
154830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifdef TIXML_USE_STL
154930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag )
155030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
155130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	while ( in->good() )
155230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
155330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		int c = in->get();
155430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( c <= 0 )
155530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
155630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TiXmlDocument* document = GetDocument();
155730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			if ( document )
155830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
155930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return;
156030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
156130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		(*tag) += (char) c;
156230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
156330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( c == '>' )
156430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
156530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// All is well.
156630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return;
156730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
156830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
156930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
157030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
157130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
157230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunconst char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding )
157330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
157430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	p = SkipWhiteSpace( p, _encoding );
157530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// Find the beginning, find the end, and look for
157630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	// the stuff in-between.
157730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	TiXmlDocument* document = GetDocument();
157830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( !p || !*p || !StringEqual( p, "<?xml", true, _encoding ) )
157930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
158030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding );
158130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		return 0;
158230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
158330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	if ( data )
158430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
158530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		data->Stamp( p, _encoding );
158630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		location = data->Cursor();
158730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
158830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	p += 5;
158930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
159030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	version = "";
159130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	encoding = "";
159230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	standalone = "";
159330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
159430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	while ( p && *p )
159530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	{
159630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( *p == '>' )
159730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
159830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			++p;
159930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return p;
160030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
160130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
160230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		p = SkipWhiteSpace( p, _encoding );
160330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( StringEqual( p, "version", true, _encoding ) )
160430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
160530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TiXmlAttribute attrib;
160630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			p = attrib.Parse( p, data, _encoding );
160730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			version = attrib.Value();
160830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
160930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		else if ( StringEqual( p, "encoding", true, _encoding ) )
161030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
161130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TiXmlAttribute attrib;
161230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			p = attrib.Parse( p, data, _encoding );
161330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			encoding = attrib.Value();
161430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
161530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		else if ( StringEqual( p, "standalone", true, _encoding ) )
161630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
161730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			TiXmlAttribute attrib;
161830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			p = attrib.Parse( p, data, _encoding );
161930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			standalone = attrib.Value();
162030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
162130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		else
162230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		{
162330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			// Read over whatever it is.
162430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			while( p && *p && *p != '>' && !IsWhiteSpace( *p ) )
162530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun				++p;
162630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		}
162730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	}
162830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	return 0;
162930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
163030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
163130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool TiXmlText::Blank() const
163230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun{
163330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	for ( unsigned i=0; i<value.length(); i++ )
163430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun		if ( !IsWhiteSpace( value[i] ) )
163530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun			return false;
163630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun	return true;
163730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
163830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
1639