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) {
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) {
518 assert(strlen(entity[i].str) == entity[i].strLength);
552 if (*tag == 0)
return true;
554 while (*q && *tag && *q == *tag) {
570 bool caseInsensitive,
580 char cArr[4] = {0, 0, 0, 0};
582 text->append(cArr, len);
585 bool whitespace =
false;
591 if (*p ==
'\r' || *p ==
'\n') {
606 char cArr[4] = {0, 0, 0, 0};
612 text->append(cArr, len);
617 if (p) p += strlen(endTag);
632 if (!StreamTo(in,
'<', tag)) {
638 int tagIndex = (
int)tag->length();
640 while (in->good() && in->peek() !=
'>') {
644 SetError(TIXML_ERROR_EMBEDDED_nullptr, 0, 0, TIXML_ENCODING_UNKNOWN);
655 TiXmlNode* node = Identify(tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING);
658 node->StreamIn(in, tag);
659 bool isElement = node->ToElement() != 0;
669 SetError(TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN);
712 const unsigned char* pU = (
const unsigned char*)p;
733 p = node->Parse(p, &data, encoding);
778 errorDesc = errorString[errorId];
782 if (pError && data) {
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");
822 returnNode =
new TiXmlStylesheetReference();
825 TIXML_LOG(
"XML parsing Declaration\n");
827 returnNode =
new TiXmlDeclaration();
830 TIXML_LOG(
"XML parsing Comment\n");
832 returnNode =
new TiXmlComment();
835 TIXML_LOG(
"XML parsing CDATA\n");
842 TIXML_LOG(
"XML parsing Unknown(1)\n");
844 returnNode =
new TiXmlUnknown();
845 }
else if (
IsAlpha(*(p + 1)
, encoding
) || *(p + 1) ==
'_') {
847 TIXML_LOG(
"XML parsing Element\n");
849 returnNode =
new TiXmlElement(
"");
852 TIXML_LOG(
"XML parsing Unknown(2)\n");
854 returnNode =
new TiXmlUnknown();
877 TiXmlDocument* document = GetDocument();
881 TIXML_ERROR_EMBEDDED_nullptr, 0, 0, TIXML_ENCODING_UNKNOWN);
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) ==
'>') {
906 StreamWhiteSpace(in, tag);
909 if (in->good() && in->peek() !=
'<') {
912 text.StreamIn(in, tag);
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;
994 TiXmlNode* node = Identify(tagloc, TIXML_DEFAULT_ENCODING);
998 node->StreamIn(in, tag);
1036 const char* pErr = p;
1038 p = ReadName(p, &value, encoding);
1077 }
else if (*p ==
'>') {
1097 if (StringEqual(p, endTag.c_str(),
false, encoding)) {
1098 p += endTag.length();
1117 attrib->SetDocument(document);
1133 TiXmlAttribute* node = attributeSet.Find(attrib->Name());
1142 attributeSet.Add(attrib);
1155 const char* pWithWhiteSpace = p;
1175 p = textNode
->Parse(pWithWhiteSpace
, data
, encoding
);
1179 LinkEndChild(textNode);
1189 TiXmlNode* node = Identify(p, encoding);
1192 p = node->Parse(p, data, encoding);
1200 pWithWhiteSpace = p;
1214 while (in->good()) {
1218 TiXmlDocument* document = GetDocument();
1222 TIXML_ERROR_EMBEDDED_nullptr, 0, 0, TIXML_ENCODING_UNKNOWN);
1248 if (!p || !*p || *p !=
'<') {
1258 while (p && *p && *p !=
'>') {
1267 if (*p ==
'>')
return p + 1;
1274 while (in->good()) {
1278 TiXmlDocument* document = GetDocument();
1282 TIXML_ERROR_EMBEDDED_nullptr, 0, 0, TIXML_ENCODING_UNKNOWN);
1289 if (c ==
'>' && tag->at(tag->length() - 2) ==
'-' &&
1290 tag->at(tag->length() - 3) ==
'-') {
1311 const char* startTag =
"<!--";
1312 const char* endTag =
"-->";
1319 p += strlen(startTag);
1356 if (p) p += strlen(endTag);
1366 if (!p || !*p)
return 0;
1378 const char* pErr = p;
1379 p = ReadName(p, &name, encoding);
1383 document->SetError(TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding);
1390 if (!p || !*p || *p !=
'=') {
1392 document->SetError(TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding);
1402 document->SetError(TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding);
1408 const char SINGLE_QUOTE =
'\'';
1409 const char DOUBLE_QUOTE =
'\"';
1411 if (*p == SINGLE_QUOTE) {
1414 p = ReadText(p, &value,
false, end,
false, encoding);
1415 }
else if (*p == DOUBLE_QUOTE) {
1418 p = ReadText(p, &value,
false, end,
false, encoding);
1429 *p !=
'/' && *p !=
'>') {
1430 if (*p == SINGLE_QUOTE || *p == DOUBLE_QUOTE) {
1436 document->SetError(TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding);
1451 while (in->good()) {
1454 if (!cdata && (c ==
'<')) {
1459 TiXmlDocument* document = GetDocument();
1463 TIXML_ERROR_EMBEDDED_nullptr, 0, 0, TIXML_ENCODING_UNKNOWN);
1471 if (cdata && c ==
'>' && tag->size() >= 3) {
1472 size_t len = tag->size();
1474 if ((*tag)[len - 2] ==
']' && (*tag)[len - 3] ==
']') {
1493 const char*
const startTag =
"<![CDATA[";
1494 const char*
const endTag =
"]]>";
1504 p += strlen(startTag);
1513 p = ReadText(p, &dummy,
false, endTag,
false, encoding);
1516 bool ignoreWhite =
true;
1518 const char* end =
"<";
1519 p = ReadText(p, &value, ignoreWhite, end,
false, encoding);
1521 if (p)
return p - 1;
1529 while (in->good()) {
1533 TiXmlDocument* document = GetDocument();
1537 TIXML_ERROR_EMBEDDED_nullptr, 0, 0, TIXML_ENCODING_UNKNOWN);
1589 version = attrib.Value();
1593 encoding = attrib.Value();
1597 standalone = attrib.Value();
1609 for (
unsigned i = 0; i < value.length(); i++)
1610 if (!IsWhiteSpace(value[i]))
return false;
1617 while (in->good()) {
1621 TiXmlDocument* document = GetDocument();
1625 TIXML_ERROR_EMBEDDED_nullptr, 0, 0, TIXML_ENCODING_UNKNOWN);
1676 type = attrib.Value();
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.
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)
static int ToLower(int v, TiXmlEncoding encoding)
static int IsAlphaNum(unsigned char anyByte, TiXmlEncoding encoding)
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
const unsigned char TIXML_UTF_LEAD_2
friend class TiXmlDocument
TiXmlAttribute()
Construct an empty attribute.
void ClearError()
If you have handled the error, it can be reset with this call.
const TiXmlCursor & Cursor()
static void ConvertUTF32ToUTF8(unsigned long input, char *output, int *length)
static bool condenseWhiteSpace
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.
static bool IsWhiteSpaceCondensed()
Return the current white space setting.
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.
friend class TiXmlElement
Always the top level node.
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)
virtual TiXmlDeclaration * ToDeclaration()
Cast to a more defined type. Will return null if not of the requested type.
const char * ReadValue(const char *in, TiXmlParsingData *prevData, TiXmlEncoding encoding)
static bool IsWhiteSpace(int c)
static const char * GetEntity(const char *in, char *value, int *length, TiXmlEncoding encoding)
TiXmlBase is a base class for every class in TinyXml.
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.
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)
TiXmlText(const char *initValue)
Constructor for text element.
virtual void StreamIn(std::istream *in, TIXML_STRING *tag)
TiXmlParsingData(const char *start, int _tabsize, int row, int col)
void SetValue(const char *_value)
Set the value.
static int IsAlpha(unsigned char anyByte, TiXmlEncoding encoding)
The element is a container class.
TiXmlCursor errorLocation