// --------------------------------------------------------------------- // // internal Properties // // --------------------------------------------------------------------- #region internal Properties #endregion internal Properties // --------------------------------------------------------------------- // // Private Methods // // --------------------------------------------------------------------- #region Private Methods // Helper for Parse method. private XamlToRtfError ParseXTokStartElement(XamlToken xamlToken, ref string name) { XamlToRtfError xamlToRtfError = _xamlAttributes.Init(xamlToken.Text); if (xamlToRtfError == XamlToRtfError.None) { xamlToRtfError = _xamlAttributes.GetTag(ref name); if (xamlToRtfError == XamlToRtfError.None) { xamlToRtfError = _xamlContent.StartElement(string.Empty, name, name, _xamlAttributes); if (xamlToRtfError == XamlToRtfError.None) { if (_xamlAttributes.IsEmpty) { xamlToRtfError = _xamlContent.EndElement(string.Empty, name, name); } else { xamlToRtfError = (XamlToRtfError)_xamlTagStack.Push(name); } } } } return(xamlToRtfError); }
// Helper for Parse method. private XamlToRtfError ParseXTokEndElement(XamlToken xamlToken, ref string name) { XamlToRtfError xamlToRtfError = _xamlAttributes.Init(xamlToken.Text); if (xamlToRtfError == XamlToRtfError.None) { xamlToRtfError = _xamlAttributes.GetTag(ref name); if (xamlToRtfError == XamlToRtfError.None) { if (_xamlTagStack.IsMatchTop(name)) { _xamlTagStack.Pop(); xamlToRtfError = _xamlContent.EndElement(string.Empty, name, name); } } } return(xamlToRtfError); }
// --------------------------------------------------------------------- // // internal Methods // // --------------------------------------------------------------------- #region internal Methods internal XamlToRtfError Parse() { // Need callbacks if (_xamlContent == null || _xamlError == null) { return XamlToRtfError.Unknown; } // We are simply looking for well-formedness: that is, that the XML is lexically valid and tags are balanced. XamlToRtfError xamlToRtfError = XamlToRtfError.None; XamlToken xamlToken = new XamlToken(); string name = string.Empty; // Fire things off xamlToRtfError = _xamlContent.StartDocument(); while (xamlToRtfError == XamlToRtfError.None) { xamlToRtfError = _xamlLexer.Next(xamlToken); if (xamlToRtfError != XamlToRtfError.None || xamlToken.TokenType == XamlTokenType.XTokEOF) { break; } switch (xamlToken.TokenType) { case XamlTokenType.XTokInvalid: xamlToRtfError = XamlToRtfError.Unknown; break; case XamlTokenType.XTokCharacters: xamlToRtfError = _xamlContent.Characters(xamlToken.Text); break; case XamlTokenType.XTokEntity: xamlToRtfError = _xamlContent.SkippedEntity(xamlToken.Text); break; case XamlTokenType.XTokStartElement: xamlToRtfError = ParseXTokStartElement(xamlToken, ref name); break; case XamlTokenType.XTokEndElement: xamlToRtfError = ParseXTokEndElement(xamlToken, ref name); break; case XamlTokenType.XTokCData: // Ignore break; case XamlTokenType.XTokPI: // Ignore break; case XamlTokenType.XTokComment: // Ignore break; case XamlTokenType.XTokWS: xamlToRtfError = _xamlContent.IgnorableWhitespace(xamlToken.Text); break; default: xamlToRtfError = XamlToRtfError.Unknown; break; } } // All tags need to have been popped. if (xamlToRtfError == XamlToRtfError.None && _xamlTagStack.Count != 0) { xamlToRtfError = XamlToRtfError.Unknown; } // Wrap things up if (xamlToRtfError == XamlToRtfError.None) { xamlToRtfError = _xamlContent.EndDocument(); } return xamlToRtfError; }
// Helper for the Next method, handles '<' token. private void NextLessThanToken(XamlToken token) { _xamlIndex++; // Careful... if (!IsCharsAvailable(1)) { token.TokenType = XamlTokenType.XTokInvalid; return; } // Default is we're going to see an invalid sequence token.TokenType = XamlTokenType.XTokInvalid; char currentChar = _xaml[_xamlIndex]; switch (currentChar) { case '?': // Processing Instruction for (_xamlIndex++; IsCharsAvailable(2); _xamlIndex++) { if (_xaml[_xamlIndex] == '?' && _xaml[_xamlIndex + 1] == '>') { _xamlIndex += 2; token.TokenType = XamlTokenType.XTokPI; break; } } break; case '!': // Comment - _xamlIndex++; for (; IsCharsAvailable(3); _xamlIndex++) { if (_xaml[_xamlIndex] == '-' && _xaml[_xamlIndex + 1] == '-' && _xaml[_xamlIndex + 2] == '>') { _xamlIndex += 3; token.TokenType = XamlTokenType.XTokComment; break; } } break; case '>': // Anomaly _xamlIndex++; token.TokenType = XamlTokenType.XTokInvalid; break; case '/': // End Element for (_xamlIndex++; IsCharsAvailable(1); _xamlIndex++) { if (_xaml[_xamlIndex] == '>') { _xamlIndex++; token.TokenType = XamlTokenType.XTokEndElement; break; } } break; default: // Start Element // Tricky element here is making sure we correctly parse quoted strings so that we don't // incorrectly treat a '>' in a string as ending the token. { char quoteChar = (char)0x00; for (; IsCharsAvailable(1); _xamlIndex++) { if (quoteChar != 0x00) { if (_xaml[_xamlIndex] == quoteChar) { quoteChar = (char)0x00; } } else if (_xaml[_xamlIndex] == '"' || _xaml[_xamlIndex] == '\'') { quoteChar = _xaml[_xamlIndex]; } else if (_xaml[_xamlIndex] == '>') { _xamlIndex++; token.TokenType = XamlTokenType.XTokStartElement; break; } } } break; } }
// --------------------------------------------------------------------- // // internal Methods // // --------------------------------------------------------------------- #region internal Methods internal XamlToRtfError Next(XamlToken token) { XamlToRtfError xamlToRtfError = XamlToRtfError.None; int startIndex = _xamlIndex; if (_xamlIndex < _xaml.Length) { char tokenChar = _xaml[_xamlIndex]; switch (tokenChar) { case ' ': case '\t': case '\r': case '\n': token.TokenType = XamlTokenType.XTokWS; for (_xamlIndex++; IsCharsAvailable(1) && IsSpace(_xaml[_xamlIndex]); _xamlIndex++) { continue; } break; case '<': NextLessThanToken(token); break; case '&': // Entity token.TokenType = XamlTokenType.XTokInvalid; for (_xamlIndex++; IsCharsAvailable(1); _xamlIndex++) { if (_xaml[_xamlIndex] == ';') { _xamlIndex++; token.TokenType = XamlTokenType.XTokEntity; break; } } break; default: // Plain text token.TokenType = XamlTokenType.XTokCharacters; for (_xamlIndex++; IsCharsAvailable(1); _xamlIndex++) { if (_xaml[_xamlIndex] == '&' || _xaml[_xamlIndex] == '<') { break; } } break; } } token.Text = _xaml.Substring(startIndex, _xamlIndex - startIndex); if (token.Text.Length == 0) { token.TokenType = XamlTokenType.XTokEOF; } return xamlToRtfError; }
// Helper for Parse method. private XamlToRtfError ParseXTokEndElement(XamlToken xamlToken, ref string name) { XamlToRtfError xamlToRtfError = _xamlAttributes.Init(xamlToken.Text); if (xamlToRtfError == XamlToRtfError.None) { xamlToRtfError = _xamlAttributes.GetTag(ref name); if (xamlToRtfError == XamlToRtfError.None) { if (_xamlTagStack.IsMatchTop(name)) { _xamlTagStack.Pop(); xamlToRtfError = _xamlContent.EndElement(string.Empty, name, name); } } } return xamlToRtfError; }
// --------------------------------------------------------------------- // // internal Properties // // --------------------------------------------------------------------- #region internal Properties #endregion internal Properties // --------------------------------------------------------------------- // // Private Methods // // --------------------------------------------------------------------- #region Private Methods // Helper for Parse method. private XamlToRtfError ParseXTokStartElement(XamlToken xamlToken, ref string name) { XamlToRtfError xamlToRtfError = _xamlAttributes.Init(xamlToken.Text); if (xamlToRtfError == XamlToRtfError.None) { xamlToRtfError = _xamlAttributes.GetTag(ref name); if (xamlToRtfError == XamlToRtfError.None) { xamlToRtfError = _xamlContent.StartElement(string.Empty, name, name, _xamlAttributes); if (xamlToRtfError == XamlToRtfError.None) { if (_xamlAttributes.IsEmpty) { xamlToRtfError = _xamlContent.EndElement(string.Empty, name, name); } else { xamlToRtfError = (XamlToRtfError)_xamlTagStack.Push(name); } } } } return xamlToRtfError; }
// --------------------------------------------------------------------- // // internal Methods // // --------------------------------------------------------------------- #region internal Methods internal XamlToRtfError Parse() { // Need callbacks if (_xamlContent == null || _xamlError == null) { return(XamlToRtfError.Unknown); } // We are simply looking for well-formedness: that is, that the XML is lexically valid and tags are balanced. XamlToRtfError xamlToRtfError = XamlToRtfError.None; XamlToken xamlToken = new XamlToken(); string name = string.Empty; // Fire things off xamlToRtfError = _xamlContent.StartDocument(); while (xamlToRtfError == XamlToRtfError.None) { xamlToRtfError = _xamlLexer.Next(xamlToken); if (xamlToRtfError != XamlToRtfError.None || xamlToken.TokenType == XamlTokenType.XTokEOF) { break; } switch (xamlToken.TokenType) { case XamlTokenType.XTokInvalid: xamlToRtfError = XamlToRtfError.Unknown; break; case XamlTokenType.XTokCharacters: xamlToRtfError = _xamlContent.Characters(xamlToken.Text); break; case XamlTokenType.XTokEntity: xamlToRtfError = _xamlContent.SkippedEntity(xamlToken.Text); break; case XamlTokenType.XTokStartElement: xamlToRtfError = ParseXTokStartElement(xamlToken, ref name); break; case XamlTokenType.XTokEndElement: xamlToRtfError = ParseXTokEndElement(xamlToken, ref name); break; case XamlTokenType.XTokCData: // Ignore break; case XamlTokenType.XTokPI: // Ignore break; case XamlTokenType.XTokComment: // Ignore break; case XamlTokenType.XTokWS: xamlToRtfError = _xamlContent.IgnorableWhitespace(xamlToken.Text); break; default: xamlToRtfError = XamlToRtfError.Unknown; break; } } // All tags need to have been popped. if (xamlToRtfError == XamlToRtfError.None && _xamlTagStack.Count != 0) { xamlToRtfError = XamlToRtfError.Unknown; } // Wrap things up if (xamlToRtfError == XamlToRtfError.None) { xamlToRtfError = _xamlContent.EndDocument(); } return(xamlToRtfError); }
// Helper for the Next method, handles '<' token. private void NextLessThanToken(XamlToken token) { _xamlIndex++; // Careful... if (!IsCharsAvailable(1)) { token.TokenType = XamlTokenType.XTokInvalid; return; } // Default is we're going to see an invalid sequence token.TokenType = XamlTokenType.XTokInvalid; char currentChar = _xaml[_xamlIndex]; switch (currentChar) { case '?': // Processing Instruction for (_xamlIndex++; IsCharsAvailable(2); _xamlIndex++) { if (_xaml[_xamlIndex] == '?' && _xaml[_xamlIndex + 1] == '>') { _xamlIndex += 2; token.TokenType = XamlTokenType.XTokPI; break; } } break; case '!': // Comment - _xamlIndex++; for (; IsCharsAvailable(3); _xamlIndex++) { if (_xaml[_xamlIndex] == '-' && _xaml[_xamlIndex + 1] == '-' && _xaml[_xamlIndex + 2] == '>') { _xamlIndex += 3; token.TokenType = XamlTokenType.XTokComment; break; } } break; case '>': // Anomaly _xamlIndex++; token.TokenType = XamlTokenType.XTokInvalid; break; case '/': // End Element for (_xamlIndex++; IsCharsAvailable(1); _xamlIndex++) { if (_xaml[_xamlIndex] == '>') { _xamlIndex++; token.TokenType = XamlTokenType.XTokEndElement; break; } } break; default: // Start Element // Tricky element here is making sure we correctly parse quoted strings so that we don't // incorrectly treat a '>' in a string as ending the token. { char quoteChar = (char)0x00; for (; IsCharsAvailable(1); _xamlIndex++) { if (quoteChar != 0x00) { if (_xaml[_xamlIndex] == quoteChar) { quoteChar = (char)0x00; } } else if (_xaml[_xamlIndex] == '"' || _xaml[_xamlIndex] == '\'') { quoteChar = _xaml[_xamlIndex]; } else if (_xaml[_xamlIndex] == '>') { _xamlIndex++; token.TokenType = XamlTokenType.XTokStartElement; break; } } } break; } }
// --------------------------------------------------------------------- // // internal Methods // // --------------------------------------------------------------------- #region internal Methods internal XamlToRtfError Next(XamlToken token) { XamlToRtfError xamlToRtfError = XamlToRtfError.None; int startIndex = _xamlIndex; if (_xamlIndex < _xaml.Length) { char tokenChar = _xaml[_xamlIndex]; switch (tokenChar) { case ' ': case '\t': case '\r': case '\n': token.TokenType = XamlTokenType.XTokWS; for (_xamlIndex++; IsCharsAvailable(1) && IsSpace(_xaml[_xamlIndex]); _xamlIndex++) { continue; } break; case '<': NextLessThanToken(token); break; case '&': // Entity token.TokenType = XamlTokenType.XTokInvalid; for (_xamlIndex++; IsCharsAvailable(1); _xamlIndex++) { if (_xaml[_xamlIndex] == ';') { _xamlIndex++; token.TokenType = XamlTokenType.XTokEntity; break; } } break; default: // Plain text token.TokenType = XamlTokenType.XTokCharacters; for (_xamlIndex++; IsCharsAvailable(1); _xamlIndex++) { if (_xaml[_xamlIndex] == '&' || _xaml[_xamlIndex] == '<') { break; } } break; } } token.Text = _xaml.Substring(startIndex, _xamlIndex - startIndex); if (token.Text.Length == 0) { token.TokenType = XamlTokenType.XTokEOF; } return(xamlToRtfError); }