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);
226 int row = cursor.row;
227 int col = cursor.col;
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)
327 assert(cursor.row >= -1);
328 assert(cursor.col >= -1);
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);
1130 #ifdef TIXML_USE_STL 1142 attributeSet.Add(attrib);
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;
1212 #ifdef TIXML_USE_STL 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;
1272 #ifdef TIXML_USE_STL 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) {
1449 #ifdef TIXML_USE_STL 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 =
"]]>";
1496 if (cdata ||
StringEqual(p, startTag,
false, encoding)) {
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;
1527 #ifdef TIXML_USE_STL 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);
1589 version = attrib.
Value();
1590 }
else if (
StringEqual(p,
"encoding",
true, _encoding)) {
1592 p = attrib.
Parse(p, data, _encoding);
1593 encoding = attrib.
Value();
1594 }
else if (
StringEqual(p,
"standalone",
true, _encoding)) {
1596 p = attrib.
Parse(p, data, _encoding);
1597 standalone = attrib.
Value();
1609 for (
unsigned i = 0; i <
value.length(); i++)
1615 #ifdef TIXML_USE_STL 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);
1680 href = attrib.
Value();
static const int utf8ByteTable[256]
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)
An attribute is a name-value pair.
friend class TiXmlElement
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)=0
const char * Name() const
Return the name of this attribute.
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)
static int ToLower(int v, TiXmlEncoding encoding)
static int IsAlphaNum(unsigned char anyByte, TiXmlEncoding encoding)
virtual const TiXmlElement * ToElement() const
Cast to a more defined type. Will return null if not of the requested type.
static const char * ReadName(const char *p, TIXML_STRING *name, TiXmlEncoding encoding)
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
const unsigned char TIXML_UTF_LEAD_2
const TIXML_STRING & NameTStr() const
void ClearError()
If you have handled the error, it can be reset with this call.
const TiXmlCursor & Cursor()
static const char * errorString[TIXML_ERROR_STRING_COUNT]
static void ConvertUTF32ToUTF8(unsigned long input, char *output, int *length)
static bool condenseWhiteSpace
TiXmlNode * LinkEndChild(TiXmlNode *addThis)
Add a new node related to this.
const char * Encoding() const
Encoding. Will return an empty string if none was found.
A stylesheet reference looks like this:
In correct XML the declaration is the first entry in the file.
const char * Value() const
Return the value of this attribute.
static bool IsWhiteSpace(char c)
Any tag that tinyXml doesn't recognize is saved as an unknown.
const TiXmlEncoding TIXML_DEFAULT_ENCODING
static bool IsWhiteSpaceCondensed()
Return the current white space setting.
static const char * ReadText(const char *in, TIXML_STRING *text, bool ignoreWhiteSpace, const char *endTag, bool ignoreCase, TiXmlEncoding encoding)
const unsigned char TIXML_UTF_LEAD_1
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)
void SetCDATA(bool _cdata)
Turns on or off a CDATA representation of text.
Always the top level node.
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)=0
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)
const unsigned char TIXML_UTF_LEAD_0
static Entity entity[NUM_ENTITY]
static const char * SkipWhiteSpace(const char *, TiXmlEncoding encoding)
TiXmlNode * Identify(const char *start, TiXmlEncoding encoding)
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
static bool StreamTo(std::istream *in, int character, TIXML_STRING *tag)
const char * ReadValue(const char *in, TiXmlParsingData *prevData, TiXmlEncoding encoding)
const TiXmlDocument * GetDocument() const
Return a pointer to the Document this node lives in.
static const char * GetEntity(const char *in, char *value, int *length, TiXmlEncoding encoding)
virtual const char * Parse(const char *p, TiXmlParsingData *data, TiXmlEncoding encoding)
static bool StringEqual(const char *p, const char *endTag, bool ignoreCase, 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.
virtual const TiXmlDeclaration * ToDeclaration() const
Cast to a more defined type. Will return null if not of the requested type.
void SetError(int err, const char *errorLocation, TiXmlParsingData *prevData, TiXmlEncoding encoding)
The parent class for everything in the Document Object Model.
void Stamp(const char *now, TiXmlEncoding encoding)
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
static const char * GetChar(const char *p, char *_value, int *length, TiXmlEncoding encoding)
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
TiXmlParsingData(const char *start, int _tabsize, int row, int col)
void SetDocument(TiXmlDocument *doc)
void SetValue(const char *_value)
Set the value.
static int IsAlpha(unsigned char anyByte, TiXmlEncoding encoding)
static bool StreamWhiteSpace(std::istream *in, TIXML_STRING *tag)
TiXmlCursor errorLocation