public override int Parse(string p, int index, TiXmlParsingData data, int encoding) { value = ""; TiXmlDocument document = GetDocument(); if (data != null) { data.Stamp(p, index, encoding); location = data.Cursor(); } const string startTag = "<![CDATA["; const string endTag = "]]>"; if (cdata || StringEqual(p, index, startTag, false, encoding)) { StringBuilder _value = new StringBuilder(); cdata = true; if (!StringEqual(p, index, startTag, false, encoding)) { document.SetError(ErrorType.TIXML_ERROR_PARSING_CDATA, p, index, data, encoding); return(INVALID_STRING_INDEX); } index += startTag.Length; // Keep all the white space, ignore the encoding, etc. while (index >= 0 && index < p.Length && !StringEqual(p, index, endTag, false, encoding)) { //value += p[index]; _value.Append(p[index]); ++index; } value = _value.ToString(); StringBuilder dummy = _value; index = ReadText(p, index, dummy, false, endTag, false, encoding); return(index); } else { StringBuilder _value = new StringBuilder(); bool ignoreWhite = true; string end = "<"; index = ReadText(p, index, _value, ignoreWhite, end, false, encoding); value = _value.ToString(); if (index >= 0) { return(index - 1); // don't truncate the '<' } return(INVALID_STRING_INDEX); } }
public override int Parse(string p, int index, TiXmlParsingData data, int encoding) { TiXmlDocument document = GetDocument(); index = SkipWhiteSpace(p, index, encoding); if (data != null) { data.Stamp(p, index, encoding); location = data.Cursor(); } //if ( !p || !*p || *p != '<' ) if (index < 0 || index >= p.Length || p[index] != '<') { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_PARSING_UNKNOWN, p, index, data, encoding); } return(0); } ++index; value = ""; StringBuilder _value = new StringBuilder(); //while ( p && *p && *p != '>' ) while (index >= 0 && index < p.Length && p[index] != '>') { //value += p[index]; _value.Append(p[index]); ++index; } if (index < 0) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_PARSING_UNKNOWN, null, 0, null, encoding); } return(INVALID_STRING_INDEX); } value = _value.ToString(); if (p[index] == '>') { return(index + 1); } return(index); }
// [internal use] public void SetError(ErrorType err, string pError, int index, TiXmlParsingData data, int encoding) { // The first error in a chain is more accurate - don't set again! if (error) { return; } //assert( err > 0 && err < TIXML_ERROR_STRING_COUNT ); error = true; errorId = err; errorDesc = errorString[(int)errorId]; errorLocation.Clear(); if (pError != null && data != null) { data.Stamp(pError, index, encoding); errorLocation = data.Cursor(); } }
/// <summary> /// Attribute parsing starts: first letter of the name /// </summary> /// <returns>the next char after the value end quote</returns> public override int Parse(string p, int index, TiXmlParsingData data, int encoding) { index = SkipWhiteSpace(p, index, encoding); if (index < 0 || index >= p.Length) { return(-1); } // int tabsize = 4; // if ( document ) // tabsize = document.TabSize(); if (data != null) { data.Stamp(p, index, encoding); location = data.Cursor(); } // Read the name, the '=' and the value. int pErr = index; index = ReadName(p, index, ref name, encoding); //if ( !p || !*p ) if (index < 0 || index >= p.Length) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_READING_ATTRIBUTES, p, pErr, data, encoding); } return(0); } index = SkipWhiteSpace(p, index, encoding); //if ( !p || !*p || *p != '=' ) if (index < 0 || index >= p.Length || p[index] != '=') { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_READING_ATTRIBUTES, p, index, data, encoding); } return(0); } ++index; // skip '=' index = SkipWhiteSpace(p, index, encoding); if (index < 0 || index >= p.Length) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_READING_ATTRIBUTES, p, index, data, encoding); } return(0); } string end; const char SINGLE_QUOTE = '\''; const char DOUBLE_QUOTE = '\"'; StringBuilder _value = new StringBuilder(); if (p[index] == SINGLE_QUOTE) { ++index; end = "\'"; // single quote in string index = ReadText(p, index, _value, false, end, false, encoding); } else if (p[index] == DOUBLE_QUOTE) { ++index; end = "\""; // double quote in string index = ReadText(p, index, _value, false, end, false, encoding); } else { // All attribute values should be in single or double quotes. // But this is such a common error that the parser will try // its best, even without them. value = ""; while (index >= 0 && index < p.Length && // existence !IsWhiteSpace(p[index]) && p[index] != '\n' && p[index] != '\r' && // whitespace p[index] != '/' && p[index] != '>') // tag end { if (p[index] == SINGLE_QUOTE || p[index] == DOUBLE_QUOTE) { // [ 1451649 ] Attribute values with trailing quotes not handled correctly // We did not have an opening quote but seem to have a // closing one. Give up and throw an error. if (document != null) { document.SetError(ErrorType.TIXML_ERROR_READING_ATTRIBUTES, p, index, data, encoding); } return(INVALID_STRING_INDEX); } //value += p[index]; _value.Append(p[index]); ++index; } } value = _value.ToString(); return(index); }
/// <summary> /// Parse the given null terminated block of xml data. Passing in an encoding to this /// method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml /// to use that encoding, regardless of what TinyXml might otherwise try to detect. /// </summary> public override int Parse(string p, int index, TiXmlParsingData prevData /* = null*/, int encoding /* = TIXML_DEFAULT_ENCODING*/) { ClearError(); // Parse away, at the document level. Since a document // contains nothing but other tags, most of what happens // here is skipping white space. //if ( !p || !*p ) if (p == null || index < 0 || index >= p.Length) { SetError(ErrorType.TIXML_ERROR_DOCUMENT_EMPTY, null, 0, null, TiXmlEncoding.TIXML_ENCODING_UNKNOWN); return(0); } // Note that, for a document, this needs to come // before the while space skip, so that parsing // starts from the pointer we are given. location.Clear(); if (prevData != null) { location.row = prevData.cursor.row; location.col = prevData.cursor.col; } else { location.row = 0; location.col = 0; } TiXmlParsingData data = new TiXmlParsingData(p, index, TabSize(), location.row, location.col); location = data.Cursor(); #if UNUSED if (encoding == TiXmlEncoding.TIXML_ENCODING_UNKNOWN) { // Check for the Microsoft UTF-8 lead bytes. const unsigned char *pU = (const unsigned char *)p; if (*(pU + 0) && *(pU + 0) == TIXML_UTF_LEAD_0 && *(pU + 1) && *(pU + 1) == TIXML_UTF_LEAD_1 && *(pU + 2) && *(pU + 2) == TIXML_UTF_LEAD_2) { encoding = TIXML_ENCODING_UTF8; useMicrosoftBOM = true; } } #endif index = SkipWhiteSpace(p, index, encoding); //if ( !p ) if (index < 0) { SetError(ErrorType.TIXML_ERROR_DOCUMENT_EMPTY, null, 0, null, TiXmlEncoding.TIXML_ENCODING_UNKNOWN); return(-1); } while (index >= 0 && index < p.Length) { TiXmlNode node = Identify(p, index, encoding); if (node != null) { index = node.Parse(p, index, data, encoding); LinkEndChild(node); } else { break; } // Did we get encoding info? if (encoding == TiXmlEncoding.TIXML_ENCODING_UNKNOWN && node.ToDeclaration() != null) { TiXmlDeclaration dec = node.ToDeclaration(); string enc = dec.Encoding(); //assert( enc ); if (enc.Length == 0 /**enc == 0 */) { encoding = TiXmlEncoding.TIXML_ENCODING_UTF8; } else if (StringEqual(enc, 0, "UTF-8", true, TiXmlEncoding.TIXML_ENCODING_UNKNOWN)) { encoding = TiXmlEncoding.TIXML_ENCODING_UTF8; } else if (StringEqual(enc, 0, "UTF8", true, TiXmlEncoding.TIXML_ENCODING_UNKNOWN)) { encoding = TiXmlEncoding.TIXML_ENCODING_UTF8; // incorrect, but be nice } else { encoding = TiXmlEncoding.TIXML_ENCODING_LEGACY; } } index = SkipWhiteSpace(p, index, encoding); } // Was this empty? if (firstChild == null) { SetError(ErrorType.TIXML_ERROR_DOCUMENT_EMPTY, null, 0, null, encoding); return(INVALID_STRING_INDEX); } // All is well. return(index); }
/* Attribtue parsing starts: next char past '<' * returns: next char past '>' */ public override int Parse(string p, int index, TiXmlParsingData data, int encoding) { index = SkipWhiteSpace(p, index, encoding); TiXmlDocument document = GetDocument(); if (p == null || index < 0 || index >= p.Length) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_PARSING_ELEMENT, null, 0, null, encoding); } return(0); } if (data != null) { data.Stamp(p, index, encoding); location = data.Cursor(); } if (p[index] != '<') { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_PARSING_ELEMENT, p, index, data, encoding); } return(0); } index = SkipWhiteSpace(p, index + 1, encoding); // Read the name. int pErr = index; index = ReadName(p, index, ref value, encoding); if (index < 0 || index >= p.Length) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, p, pErr, data, encoding); } return(INVALID_STRING_INDEX); } string endTag = "</"; endTag += value; endTag += ">"; // Check for and read attributes. Also look for an empty // tag or an end tag. while (index >= 0 && index < p.Length) { pErr = index; index = SkipWhiteSpace(p, index, encoding); if (index < 0 || index >= p.Length) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_READING_ATTRIBUTES, p, pErr, data, encoding); } return(-1); } if (p[index] == '/') { ++index; // Empty tag. if (p[index] != '>') { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_PARSING_EMPTY, p, index, data, encoding); } return(0); } return(index + 1); } else if (p[index] == '>') { // Done with attributes (if there were any.) // Read the value -- which can include other // elements -- read the end tag, and return. ++index; index = ReadValue(p, index, data, encoding); // Note this is an Element method, and will set the error if one happens. if (index < 0 || index >= p.Length) { // We were looking for the end tag, but found nothing. // Fix for [ 1663758 ] Failure to report error on bad XML if (document != null) { document.SetError(ErrorType.TIXML_ERROR_READING_END_TAG, p, index, data, encoding); } return(INVALID_STRING_INDEX); } // We should find the end tag now if (StringEqual(p, index, endTag, false, encoding)) { index += endTag.Length; return(index); } else { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_READING_END_TAG, p, index, data, encoding); } return(INVALID_STRING_INDEX); } } else { // Try to read an attribute: TiXmlAttribute attrib = new TiXmlAttribute(); if (attrib == null) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_OUT_OF_MEMORY, p, pErr, data, encoding); } return(-1); } attrib.SetDocument(document); pErr = index; index = attrib.Parse(p, index, data, encoding); if (index < 0 || index >= p.Length) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_PARSING_ELEMENT, p, pErr, data, encoding); } //delete attrib; return(INVALID_STRING_INDEX); } // Handle the strange case of double attributes: TiXmlAttribute node = attributeSet.Find(attrib.Name()); if (node != null) { node.SetValue(attrib.Value()); //delete attrib; return(INVALID_STRING_INDEX); } attributeSet.Add(attrib); } } return(index); }
public override int Parse(string p, int index, TiXmlParsingData data, int _encoding) { index = SkipWhiteSpace(p, index, _encoding); // Find the beginning, find the end, and look for // the stuff in-between. TiXmlDocument document = GetDocument(); if (index < 0 || index >= p.Length || !StringEqual(p, index, "<?xml", true, _encoding)) { if (document != null) { document.SetError(ErrorType.TIXML_ERROR_PARSING_DECLARATION, null, 0, null, _encoding); } return(INVALID_STRING_INDEX); } if (data != null) { data.Stamp(p, index, _encoding); location = data.Cursor(); } p += 5; version = ""; encoding = ""; standalone = ""; while (index >= 0 && index < p.Length) { if (p[index] == '>') { ++index; return(index); } index = SkipWhiteSpace(p, index, _encoding); if (StringEqual(p, index, "version", true, _encoding)) { TiXmlAttribute attrib = new TiXmlAttribute(); index = attrib.Parse(p, index, data, _encoding); version = attrib.Value(); } else if (StringEqual(p, index, "encoding", true, _encoding)) { TiXmlAttribute attrib = new TiXmlAttribute(); index = attrib.Parse(p, index, data, _encoding); encoding = attrib.Value(); } else if (StringEqual(p, index, "standalone", true, _encoding)) { TiXmlAttribute attrib = new TiXmlAttribute(); index = attrib.Parse(p, index, data, _encoding); standalone = attrib.Value(); } else { // Read over whatever it is. while (index >= 0 && index < p.Length && p[index] != '>' && !IsWhiteSpace(p[index])) { ++index; } } } return(INVALID_STRING_INDEX); }
/* Attribute parsing starts: at the ! of the !-- * returns: next char past '>' */ public override int Parse(string p, int index, TiXmlParsingData data, int encoding) { TiXmlDocument document = GetDocument(); value = ""; index = SkipWhiteSpace(p, index, encoding); if (data != null) { data.Stamp(p, index, encoding); location = data.Cursor(); } const string startTag = "<!--"; const string endTag = "-->"; if (!StringEqual(p, index, startTag, false, encoding)) { document.SetError(ErrorType.TIXML_ERROR_PARSING_COMMENT, p, index, data, encoding); return(INVALID_STRING_INDEX); } index += startTag.Length; // [ 1475201 ] TinyXML parses entities in comments // Oops - ReadText doesn't work, because we don't want to parse the entities. // p = ReadText( p, &value, false, endTag, false, encoding ); // // from the XML spec: /* * [Definition: Comments may appear anywhere in a document outside other markup; in addition, * they may appear within the document type declaration at places allowed by the grammar. * They are not part of the document's character data; an XML processor MAY, but need not, * make it possible for an application to retrieve the text of comments. For compatibility, * the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity * references MUST NOT be recognized within comments. * * An example of a comment: * * <!-- declarations for <head> & <body> -. */ value = ""; StringBuilder _value = new StringBuilder(); // Keep all the white space. //while ( p && *p && !StringEqual( p, endTag, false, encoding ) ) while (index >= 0 && index < p.Length && !StringEqual(p, index, endTag, false, encoding)) { _value.Append(p, index, 1); ++index; } if (index >= 0 && index < p.Length) { index += endTag.Length; } value = _value.ToString(); return(index); }