31 #if defined( DEBUG_PARSER )
32 #define TIXML_LOG printf
45 {
""", 6,
'\"' },
66 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
67 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
68 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
69 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
70 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
71 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
72 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
73 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
74 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
75 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
76 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
77 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
78 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
79 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
80 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
81 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
87 const unsigned long BYTE_MASK = 0xBF;
88 const unsigned long BYTE_MARK = 0x80;
89 const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
93 else if ( input < 0x800 )
95 else if ( input < 0x10000 )
97 else if ( input < 0x200000 )
100 { *length = 0;
return; }
109 *output = (char)((input | BYTE_MARK) & BYTE_MASK);
113 *output = (char)((input | BYTE_MARK) & BYTE_MASK);
117 *output = (char)((input | BYTE_MARK) & BYTE_MASK);
121 *output = (char)(input | FIRST_BYTE_MARK[*length]);
136 return isalpha( anyByte );
157 return isalnum( anyByte );
209 const char* p =
stamp;
215 const unsigned char* pU = (
const unsigned char*)p;
264 if ( *(p+1) && *(p+2) )
270 else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
272 else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
324 const unsigned char* pU = (
const unsigned char*)p;
368 if ( !in->good() )
return false;
375 *tag += (char) in->get();
385 if ( c == character )
415 && (
IsAlpha( (
unsigned char) *p, encoding ) || *p ==
'_' ) )
417 const char* start = p;
419 && (
IsAlphaNum( (
unsigned char ) *p, encoding )
429 name->assign( start, p-start );
443 if ( *(p+1) && *(p+1) ==
'#' && *(p+2) )
445 unsigned long ucs = 0;
452 if ( !*(p+3) )
return 0;
455 q = strchr( q,
';' );
457 if ( !q || !*q )
return 0;
464 if ( *q >=
'0' && *q <=
'9' )
465 ucs += mult * (*q -
'0');
466 else if ( *q >=
'a' && *q <=
'f' )
467 ucs += mult * (*q -
'a' + 10);
468 else if ( *q >=
'A' && *q <=
'F' )
469 ucs += mult * (*q -
'A' + 10 );
479 if ( !*(p+2) )
return 0;
482 q = strchr( q,
';' );
484 if ( !q || !*q )
return 0;
491 if ( *q >=
'0' && *q <=
'9' )
492 ucs += mult * (*q -
'0');
509 return p + delta + 1;
515 if ( strncmp(
entity[i].str, p,
entity[i].strLength ) == 0 )
517 assert( strlen(
entity[i].str ) ==
entity[i].strLength );
520 return ( p +
entity[i].strLength );
549 while ( *q && *tag &&
ToLower( *q, encoding ) ==
ToLower( *tag, encoding ) )
560 while ( *q && *tag && *q == *tag )
576 bool caseInsensitive,
585 && !
StringEqual( p, endTag, caseInsensitive, encoding )
589 char cArr[4] = { 0, 0, 0, 0 };
590 p =
GetChar( p, cArr, &len, encoding );
591 text->append( cArr, len );
596 bool whitespace =
false;
601 && !
StringEqual( p, endTag, caseInsensitive, encoding ) )
603 if ( *p ==
'\r' || *p ==
'\n' )
623 char cArr[4] = { 0, 0, 0, 0 };
624 p =
GetChar( p, cArr, &len, encoding );
628 text->append( cArr, len );
633 p += strlen( endTag );
634 return ( p && *p ) ? p : 0;
655 int tagIndex = (int) tag->length();
656 while ( in->good() && in->peek() !=
'>' )
733 const unsigned char* pU = (
const unsigned char*)p;
755 p = node->
Parse( p, &data, encoding );
806 if ( pError && data )
808 data->
Stamp( pError, encoding );
819 if( !p || !*p || *p !=
'<' )
838 const char* xmlHeader = {
"<?xml" };
839 const char* commentHeader = {
"<!--" };
840 const char* dtdHeader = {
"<!" };
841 const char* cdataHeader = {
"<![CDATA[" };
846 TIXML_LOG(
"XML parsing Declaration\n" );
850 else if (
StringEqual( p, commentHeader,
false, encoding ) )
853 TIXML_LOG(
"XML parsing Comment\n" );
857 else if (
StringEqual( p, cdataHeader,
false, encoding ) )
860 TIXML_LOG(
"XML parsing CDATA\n" );
866 else if (
StringEqual( p, dtdHeader,
false, encoding ) )
869 TIXML_LOG(
"XML parsing Unknown(1)\n" );
873 else if (
IsAlpha( *(p+1), encoding )
877 TIXML_LOG(
"XML parsing Element\n" );
884 TIXML_LOG(
"XML parsing Unknown(2)\n" );
892 returnNode->
parent =
this;
918 if ( tag->length() < 3 )
return;
923 if ( tag->at( tag->length() - 1 ) ==
'>'
924 && tag->at( tag->length() - 2 ) ==
'/' )
929 else if ( tag->at( tag->length() - 1 ) ==
'>' )
941 if ( in->good() && in->peek() !=
'<' )
954 if ( !in->good() )
return;
955 assert( in->peek() ==
'<' );
956 int tagIndex = (int) tag->length();
958 bool closingTag =
false;
959 bool firstCharFound =
false;
982 if ( c ==
'[' && tag->size() >= 9 )
984 size_t len = tag->size();
985 const char* start = tag->c_str() + len - 9;
986 if ( strcmp( start,
"<![CDATA[" ) == 0 ) {
987 assert( !closingTag );
992 if ( !firstCharFound && c !=
'<' && !
IsWhiteSpace( c ) )
994 firstCharFound =
true;
1023 const char* tagloc = tag->c_str() + tagIndex;
1050 data->
Stamp( p, encoding );
1063 const char* pErr = p;
1097 else if ( *p ==
'>' )
1116 if (
StringEqual( p, endTag.c_str(),
false, encoding ) )
1118 p += endTag.length();
1120 if ( p && *p && *p ==
'>' ) {
1144 p = attrib->
Parse( p, data, encoding );
1175 const char* pWithWhiteSpace = p;
1192 p = textNode->
Parse( p, data, encoding );
1198 p = textNode->
Parse( pWithWhiteSpace, data, encoding );
1201 if ( !textNode->
Blank() )
1220 p = node->
Parse( p, data, encoding );
1229 pWithWhiteSpace = p;
1243 while ( in->good() )
1271 data->
Stamp( p, encoding );
1274 if ( !p || !*p || *p !=
'<' )
1282 while ( p && *p && *p !=
'>' )
1293 if ( p && *p ==
'>' )
1300 while ( in->good() )
1314 && tag->at( tag->length() - 2 ) ==
'-'
1315 && tag->at( tag->length() - 3 ) ==
'-' )
1333 data->
Stamp( p, encoding );
1336 const char* startTag =
"<!--";
1337 const char* endTag =
"-->";
1339 if ( !
StringEqual( p, startTag,
false, encoding ) )
1345 p += strlen( startTag );
1367 while ( p && *p && !
StringEqual( p, endTag,
false, encoding ) )
1369 value.append( p, 1 );
1373 p += strlen( endTag );
1382 if ( !p || !*p )
return 0;
1386 data->
Stamp( p, encoding );
1390 const char* pErr = p;
1398 if ( !p || !*p || *p !=
'=' )
1413 const char SINGLE_QUOTE =
'\'';
1414 const char DOUBLE_QUOTE =
'\"';
1416 if ( *p == SINGLE_QUOTE )
1422 else if ( *p == DOUBLE_QUOTE )
1436 && *p !=
'/' && *p !=
'>' )
1438 if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) {
1455 while ( in->good() )
1458 if ( !
cdata && (c ==
'<' ) )
1473 if (
cdata && c ==
'>' && tag->size() >= 3 ) {
1474 size_t len = tag->size();
1475 if ( (*tag)[len-2] ==
']' && (*tag)[len-3] ==
']' ) {
1491 data->
Stamp( p, encoding );
1495 const char*
const startTag =
"<![CDATA[";
1496 const char*
const endTag =
"]]>";
1502 if ( !
StringEqual( p, startTag,
false, encoding ) )
1508 p += strlen( startTag );
1520 p =
ReadText( p, &dummy,
false, endTag,
false, encoding );
1525 bool ignoreWhite =
true;
1527 const char* end =
"<";
1528 p =
ReadText( p, &
value, ignoreWhite, end,
false, encoding );
1538 while ( in->good() )
1565 if ( !p || !*p || !
StringEqual( p,
"<?xml",
true, _encoding ) )
1572 data->
Stamp( p, _encoding );
1590 if (
StringEqual( p,
"version",
true, _encoding ) )
1593 p = attrib.
Parse( p, data, _encoding );
1596 else if (
StringEqual( p,
"encoding",
true, _encoding ) )
1599 p = attrib.
Parse( p, data, _encoding );
1602 else if (
StringEqual( p,
"standalone",
true, _encoding ) )
1605 p = attrib.
Parse( p, data, _encoding );
1620 for (
unsigned i=0; i<
value.length(); i++ )
TiXmlAttribute * Find(const char *_name) const
void Add(TiXmlAttribute *attribute)
An attribute is a name-value pair.
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)
const char * Value() const
Return the value of this attribute.
void SetDocument(TiXmlDocument *doc)
const TIXML_STRING & NameTStr() const
static bool StreamTo(std::istream *in, int character, TIXML_STRING *tag)
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)=0
static bool condenseWhiteSpace
static const char * ReadText(const char *in, TIXML_STRING *text, bool ignoreWhiteSpace, const char *endTag, bool ignoreCase, TiXmlEncoding encoding)
static int IsAlphaNum(unsigned char anyByte, TiXmlEncoding encoding)
static const char * GetEntity(const char *in, char *value, int *length, TiXmlEncoding encoding)
static bool IsWhiteSpaceCondensed()
Return the current white space setting.
static bool StringEqual(const char *p, const char *endTag, bool ignoreCase, TiXmlEncoding encoding)
static bool IsWhiteSpace(char c)
static void ConvertUTF32ToUTF8(unsigned long input, char *output, int *length)
static const int utf8ByteTable[256]
static Entity entity[NUM_ENTITY]
static int IsAlpha(unsigned char anyByte, TiXmlEncoding encoding)
static const char * GetChar(const char *p, char *_value, int *length, TiXmlEncoding encoding)
static bool StreamWhiteSpace(std::istream *in, TIXML_STRING *tag)
static const char * errorString[TIXML_ERROR_STRING_COUNT]
@ TIXML_ERROR_DOCUMENT_EMPTY
@ TIXML_ERROR_PARSING_ELEMENT
@ TIXML_ERROR_READING_END_TAG
@ TIXML_ERROR_STRING_COUNT
@ TIXML_ERROR_EMBEDDED_NULL
@ TIXML_ERROR_PARSING_EMPTY
@ TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME
@ TIXML_ERROR_PARSING_COMMENT
@ TIXML_ERROR_READING_ATTRIBUTES
@ TIXML_ERROR_PARSING_UNKNOWN
@ TIXML_ERROR_PARSING_DECLARATION
@ TIXML_ERROR_READING_ELEMENT_VALUE
@ TIXML_ERROR_PARSING_CDATA
static const char * ReadName(const char *p, TIXML_STRING *name, TiXmlEncoding encoding)
static const char * SkipWhiteSpace(const char *, TiXmlEncoding encoding)
static int ToLower(int v, TiXmlEncoding encoding)
In correct XML the declaration is the first entry in the file.
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)
const char * Encoding() const
Encoding. Will return an empty string if none was found.
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
Always the top level node.
virtual const char * Parse(const char *p, TiXmlParsingData *data=0, TiXmlEncoding encoding=TIXML_DEFAULT_ENCODING)
Parse the given null terminated block of xml data.
void SetError(int err, const char *errorLocation, TiXmlParsingData *prevData, TiXmlEncoding encoding)
void ClearError()
If you have handled the error, it can be reset with this call.
TiXmlCursor errorLocation
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)
const char * ReadValue(const char *in, TiXmlParsingData *prevData, TiXmlEncoding encoding)
TiXmlAttributeSet attributeSet
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
The parent class for everything in the Document Object Model.
TiXmlNode * LinkEndChild(TiXmlNode *addThis)
Add a new node related to this.
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)=0
virtual const TiXmlElement * ToElement() const
Cast to a more defined type. Will return null if not of the requested type.
const TiXmlDocument * GetDocument() const
Return a pointer to the Document this node lives in.
friend class TiXmlElement
virtual const TiXmlDeclaration * ToDeclaration() const
Cast to a more defined type. Will return null if not of the requested type.
TiXmlNode * Identify(const char *start, TiXmlEncoding encoding)
const TiXmlCursor & Cursor() const
void Stamp(const char *now, TiXmlEncoding encoding)
TiXmlParsingData(const char *start, int _tabsize, int row, int col)
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)
void SetCDATA(bool _cdata)
Turns on or off a CDATA representation of text.
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
Any tag that tinyXml doesn't recognize is saved as an unknown.
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
const TiXmlEncoding TIXML_DEFAULT_ENCODING
const unsigned char TIXML_UTF_LEAD_0
const unsigned char TIXML_UTF_LEAD_1
const unsigned char TIXML_UTF_LEAD_2