32#if defined(DEBUG_PARSER)
33#if defined(DEBUG) && defined(_MSC_VER)
35#define TIXML_LOG OutputDebugString
37#define TIXML_LOG printf
66 1, 1, 1, 1, 1, 1, 1, 1,
67 1, 1, 1, 1, 1, 1, 1, 1,
68 1, 1, 1, 1, 1, 1, 1, 1,
69 1, 1, 1, 1, 1, 1, 1, 1,
70 1, 1, 1, 1, 1, 1, 1, 1,
71 1, 1, 1, 1, 1, 1, 1, 1,
72 1, 1, 1, 1, 1, 1, 1, 1,
73 1, 1, 1, 1, 1, 1, 1, 1,
74 1, 1, 1, 1, 1, 1, 1, 1,
75 1, 1, 1, 1, 1, 1, 1, 1,
76 1, 1, 1, 1, 1, 1, 1, 1,
77 1, 1, 1, 1, 1, 1, 1, 1,
78 1, 1, 1, 1, 1, 1, 1, 1,
79 1, 1, 1, 1, 1, 1, 1, 1,
80 1, 1, 1, 1, 1, 1, 1, 1,
81 1, 1, 1, 1, 1, 1, 1, 1,
82 1, 1, 1, 1, 1, 1, 1, 1,
83 1, 1, 1, 1, 1, 1, 1, 1,
84 1, 1, 1, 1, 1, 1, 1, 1,
85 1, 1, 1, 1, 1, 1, 1, 1,
86 1, 1, 1, 1, 1, 1, 1, 1,
87 1, 1, 1, 1, 1, 1, 1, 1,
88 1, 1, 1, 1, 1, 1, 1, 1,
89 1, 1, 1, 1, 1, 1, 1, 1,
90 1, 1, 2, 2, 2, 2, 2, 2,
91 2, 2, 2, 2, 2, 2, 2, 2,
92 2, 2, 2, 2, 2, 2, 2, 2,
93 2, 2, 2, 2, 2, 2, 2, 2,
94 3, 3, 3, 3, 3, 3, 3, 3,
95 3, 3, 3, 3, 3, 3, 3, 3,
96 4, 4, 4, 4, 4, 1, 1, 1,
97 1, 1, 1, 1, 1, 1, 1, 1
103 const unsigned long BYTE_MASK = 0xBF;
104 const unsigned long BYTE_MARK = 0x80;
105 const unsigned long FIRST_BYTE_MARK[7] = {
106 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC};
110 else if (input < 0x800)
112 else if (input < 0x10000)
114 else if (input < 0x200000)
127 *output = (char)((input | BYTE_MARK) & BYTE_MASK);
132 *output = (char)((input | BYTE_MARK) & BYTE_MASK);
137 *output = (char)((input | BYTE_MARK) & BYTE_MASK);
142 *output = (char)(input | FIRST_BYTE_MARK[*length]);
157 return isalpha(anyByte);
181 return isalnum(anyByte);
228 const char* p =
stamp;
233 const unsigned char* pU = (
const unsigned char*)p;
283 if (*(p + 1) && *(p + 2)) {
288 else if (*(pU + 1) == 0xbfU && *(pU + 2) == 0xbeU)
290 else if (*(pU + 1) == 0xbfU && *(pU + 2) == 0xbfU)
340 const unsigned char* pU = (
const unsigned char*)p;
348 *(pU + 2) == 0xbeU) {
352 *(pU + 2) == 0xbfU) {
364 while ((*p &&
IsWhiteSpace(*p)) || *p ==
'\n' || *p ==
'\r')
374 if (!in->good())
return false;
381 *tag += (char)in->get();
391 if (c == character)
return true;
423 if (p && *p && (
IsAlpha((
unsigned char)*p, encoding) || *p ==
'_')) {
424 const char* start = p;
426 while (p && *p && (
IsAlphaNum((
unsigned char)*p, encoding) || *p ==
'_' ||
427 *p ==
'-' || *p ==
'.' || *p ==
':')) {
433 name->assign(start, p - start);
451 if (*(p + 1) && *(p + 1) ==
'#' && *(p + 2)) {
452 unsigned long ucs = 0;
456 if (*(p + 2) ==
'x') {
458 if (!*(p + 3))
return 0;
460 const char* q = p + 3;
463 if (!q || !*q)
return 0;
469 if (*q >=
'0' && *q <=
'9')
470 ucs += mult * (*q -
'0');
471 else if (*q >=
'a' && *q <=
'f')
472 ucs += mult * (*q -
'a' + 10);
473 else if (*q >=
'A' && *q <=
'F')
474 ucs += mult * (*q -
'A' + 10);
483 if (!*(p + 2))
return 0;
485 const char* q = p + 2;
488 if (!q || !*q)
return 0;
494 if (*q >=
'0' && *q <=
'9')
495 ucs += mult * (*q -
'0');
512 return p + delta + 1;
517 if (strncmp(
entity[i].str, p,
entity[i].strLength) == 0) {
521 return (p +
entity[i].strLength);
547 while (*q && *tag &&
ToLower(*q, encoding) ==
ToLower(*tag, encoding)) {
552 if (*tag == 0)
return true;
554 while (*q && *tag && *q == *tag) {
570 bool caseInsensitive,
578 while (p && *p && !
StringEqual(p, endTag, caseInsensitive, encoding)) {
580 char cArr[4] = {0, 0, 0, 0};
581 p =
GetChar(p, cArr, &len, encoding);
582 text->append(cArr, len);
585 bool whitespace =
false;
590 while (p && *p && !
StringEqual(p, endTag, caseInsensitive, encoding)) {
591 if (*p ==
'\r' || *p ==
'\n') {
606 char cArr[4] = {0, 0, 0, 0};
607 p =
GetChar(p, cArr, &len, encoding);
612 text->append(cArr, len);
617 if (p) p += strlen(endTag);
638 int tagIndex = (int)tag->length();
640 while (in->good() && in->peek() !=
'>') {
712 const unsigned char* pU = (
const unsigned char*)p;
733 p = node->
Parse(p, &data, encoding);
782 if (pError && data) {
783 data->
Stamp(pError, encoding);
793 if (!p || !*p || *p !=
'<') {
812 const char* xmlHeader = {
"<?xml"};
813 const char* xmlSSHeader = {
"<?xml-stylesheet"};
814 const char* commentHeader = {
"<!--"};
815 const char* dtdHeader = {
"<!"};
816 const char* cdataHeader = {
"<![CDATA["};
820 TIXML_LOG(
"XML parsing Stylesheet Reference\n");
823 }
else if (
StringEqual(p, xmlHeader,
true, encoding)) {
825 TIXML_LOG(
"XML parsing Declaration\n");
828 }
else if (
StringEqual(p, commentHeader,
false, encoding)) {
830 TIXML_LOG(
"XML parsing Comment\n");
833 }
else if (
StringEqual(p, cdataHeader,
false, encoding)) {
835 TIXML_LOG(
"XML parsing CDATA\n");
840 }
else if (
StringEqual(p, dtdHeader,
false, encoding)) {
842 TIXML_LOG(
"XML parsing Unknown(1)\n");
845 }
else if (
IsAlpha(*(p + 1), encoding) || *(p + 1) ==
'_') {
847 TIXML_LOG(
"XML parsing Element\n");
852 TIXML_LOG(
"XML parsing Unknown(2)\n");
859 returnNode->
parent =
this;
891 if (tag->length() < 3)
return;
896 if (tag->at(tag->length() - 1) ==
'>' && tag->at(tag->length() - 2) ==
'/') {
899 }
else if (tag->at(tag->length() - 1) ==
'>') {
909 if (in->good() && in->peek() !=
'<') {
921 if (!in->good())
return;
923 assert(in->peek() ==
'<');
924 int tagIndex = (int)tag->length();
926 bool closingTag =
false;
927 bool firstCharFound =
false;
930 if (!in->good())
return;
950 if (c ==
'[' && tag->size() >= 9) {
951 size_t len = tag->size();
952 const char* start = tag->c_str() + len - 9;
954 if (strcmp(start,
"<![CDATA[") == 0) {
961 firstCharFound =
true;
963 if (c ==
'/') closingTag =
true;
972 if (!in->good())
return;
993 const char* tagloc = tag->c_str() + tagIndex;
1022 data->
Stamp(p, encoding);
1036 const char* pErr = p;
1077 }
else if (*p ==
'>') {
1097 if (
StringEqual(p, endTag.c_str(),
false, encoding)) {
1098 p += endTag.length();
1119 p = attrib->
Parse(p, data, encoding);
1155 const char* pWithWhiteSpace = p;
1171 p = textNode->
Parse(p, data, encoding);
1175 p = textNode->
Parse(pWithWhiteSpace, data, encoding);
1178 if (!textNode->
Blank())
1192 p = node->
Parse(p, data, encoding);
1200 pWithWhiteSpace = p;
1214 while (in->good()) {
1244 data->
Stamp(p, encoding);
1248 if (!p || !*p || *p !=
'<') {
1258 while (p && *p && *p !=
'>') {
1267 if (*p ==
'>')
return p + 1;
1274 while (in->good()) {
1289 if (c ==
'>' && tag->at(tag->length() - 2) ==
'-' &&
1290 tag->at(tag->length() - 3) ==
'-') {
1307 data->
Stamp(p, encoding);
1311 const char* startTag =
"<!--";
1312 const char* endTag =
"-->";
1319 p += strlen(startTag);
1351 while (p && *p && !
StringEqual(p, endTag,
false, encoding)) {
1356 if (p) p += strlen(endTag);
1366 if (!p || !*p)
return 0;
1373 data->
Stamp(p, encoding);
1378 const char* pErr = p;
1390 if (!p || !*p || *p !=
'=') {
1408 const char SINGLE_QUOTE =
'\'';
1409 const char DOUBLE_QUOTE =
'\"';
1411 if (*p == SINGLE_QUOTE) {
1415 }
else if (*p == DOUBLE_QUOTE) {
1429 *p !=
'/' && *p !=
'>') {
1430 if (*p == SINGLE_QUOTE || *p == DOUBLE_QUOTE) {
1451 while (in->good()) {
1454 if (!
cdata && (c ==
'<')) {
1471 if (
cdata && c ==
'>' && tag->size() >= 3) {
1472 size_t len = tag->size();
1474 if ((*tag)[len - 2] ==
']' && (*tag)[len - 3] ==
']') {
1489 data->
Stamp(p, encoding);
1493 const char*
const startTag =
"<![CDATA[";
1494 const char*
const endTag =
"]]>";
1504 p += strlen(startTag);
1507 while (p && *p && !
StringEqual(p, endTag,
false, encoding)) {
1513 p =
ReadText(p, &dummy,
false, endTag,
false, encoding);
1516 bool ignoreWhite =
true;
1518 const char* end =
"<";
1521 if (p)
return p - 1;
1529 while (in->good()) {
1560 if (!p || !*p || !
StringEqual(p,
"<?xml",
true, _encoding)) {
1568 data->
Stamp(p, _encoding);
1588 p = attrib.
Parse(p, data, _encoding);
1590 }
else if (
StringEqual(p,
"encoding",
true, _encoding)) {
1592 p = attrib.
Parse(p, data, _encoding);
1594 }
else if (
StringEqual(p,
"standalone",
true, _encoding)) {
1596 p = attrib.
Parse(p, data, _encoding);
1609 for (
unsigned i = 0; i <
value.length(); i++)
1617 while (in->good()) {
1648 if (!p || !*p || !
StringEqual(p,
"<?xml-stylesheet",
true, _encoding)) {
1656 data->
Stamp(p, _encoding);
1675 p = attrib.
Parse(p, data, _encoding);
1677 }
else if (
StringEqual(p,
"href",
true, _encoding)) {
1679 p = attrib.
Parse(p, data, _encoding);
An attribute is a name-value pair.
const char * Value() const
Return the value of this attribute.
void SetValue(const char *_value)
Set the value.
const TIXML_STRING & NameTStr() const
const char * Name() const
Return the name of this attribute.
void SetDocument(TiXmlDocument *doc)
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)
static void ConvertUTF32ToUTF8(unsigned long input, char *output, int *length)
static bool StreamWhiteSpace(std::istream *in, TIXML_STRING *tag)
static const char * ReadName(const char *p, TIXML_STRING *name, TiXmlEncoding encoding)
static int IsAlphaNum(unsigned char anyByte, TiXmlEncoding encoding)
static bool condenseWhiteSpace
static bool StringEqual(const char *p, const char *endTag, bool ignoreCase, TiXmlEncoding encoding)
static const char * GetChar(const char *p, char *_value, int *length, TiXmlEncoding encoding)
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)=0
@ TIXML_ERROR_STRING_COUNT
@ TIXML_ERROR_READING_END_TAG
@ TIXML_ERROR_PARSING_UNKNOWN
@ TIXML_ERROR_PARSING_DECLARATION
@ TIXML_ERROR_PARSING_ELEMENT
@ TIXML_ERROR_PARSING_EMPTY
@ TIXML_ERROR_READING_ATTRIBUTES
@ TIXML_ERROR_PARSING_COMMENT
@ TIXML_ERROR_OUT_OF_MEMORY
@ TIXML_ERROR_PARSING_CDATA
@ TIXML_ERROR_DOCUMENT_EMPTY
@ TIXML_ERROR_EMBEDDED_nullptr
@ TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME
@ TIXML_ERROR_READING_ELEMENT_VALUE
static int ToLower(int v, TiXmlEncoding encoding)
static const char * errorString[TIXML_ERROR_STRING_COUNT]
static const char * ReadText(const char *in, TIXML_STRING *text, bool ignoreWhiteSpace, const char *endTag, bool ignoreCase, TiXmlEncoding encoding)
static bool StreamTo(std::istream *in, int character, TIXML_STRING *tag)
static Entity entity[NUM_ENTITY]
static const char * SkipWhiteSpace(const char *, TiXmlEncoding encoding)
static const char * GetEntity(const char *in, char *value, int *length, TiXmlEncoding encoding)
static const int utf8ByteTable[256]
static bool IsWhiteSpaceCondensed()
Return the current white space setting.
static int IsAlpha(unsigned char anyByte, TiXmlEncoding encoding)
static bool IsWhiteSpace(char c)
In correct XML the declaration is the first entry in the file.
const char * Encoding() const
Encoding. Will return an empty string if none was found.
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
void SetError(int err, const char *errorLocation, TiXmlParsingData *prevData, TiXmlEncoding encoding)
virtual const char * Parse(const char *p, TiXmlParsingData *data=0, TiXmlEncoding encoding=TIXML_DEFAULT_ENCODING)
Parse the given null terminated block of xml data.
TiXmlCursor errorLocation
void ClearError()
If you have handled the error, it can be reset with this call.
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
TiXmlAttributeSet attributeSet
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
const char * ReadValue(const char *in, TiXmlParsingData *prevData, TiXmlEncoding encoding)
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)
friend class TiXmlDocument
TiXmlNode * LinkEndChild(TiXmlNode *addThis)
Add a new node related to this.
TiXmlNode(NodeType _type)
virtual const TiXmlDeclaration * ToDeclaration() const
Cast to a more defined type. Will return null if not of the requested type.
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)=0
friend class TiXmlElement
TiXmlNode * Identify(const char *start, TiXmlEncoding encoding)
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 TiXmlDocument
const TiXmlCursor & Cursor()
void Stamp(const char *now, TiXmlEncoding encoding)
TiXmlParsingData(const char *start, int _tabsize, int row, int col)
A stylesheet reference looks like this:
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)
void SetCDATA(bool _cdata)
Turns on or off a CDATA representation of text.
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