public MeScanner(XamlParserContext context, string text, int lineNumber, int linePosition) { _context = context; _inputText = text; _lineNumber = lineNumber; _startPosition = linePosition; _idx = -1; _state = StringState.Value; _currentParameterName = null; _currentSpecialBracketCharacters = null; }
private SpecialBracketCharacters GetBracketCharacterForProperty(string propertyName) { SpecialBracketCharacters bracketCharacters = null; if (_context.CurrentEscapeCharacterMapForMarkupExtension != null && _context.CurrentEscapeCharacterMapForMarkupExtension.ContainsKey(propertyName)) { bracketCharacters = _context.CurrentEscapeCharacterMapForMarkupExtension[propertyName]; } return(bracketCharacters); }
private string ReadString() { bool escaped = false; char quoteChar = NullChar; bool atStart = true; bool wasQuoted = false; uint braceCount = 0; // To be compat with v3 which allowed balanced {} inside of strings StringBuilder sb = new StringBuilder(); char ch; while (!IsAtEndOfInput) { ch = CurrentChar; // handle escaping and quoting first. if (escaped) { sb.Append('\\'); sb.Append(ch); escaped = false; } else if (quoteChar != NullChar) { if (ch == Backslash) { escaped = true; } else if (ch != quoteChar) { sb.Append(ch); } else { ch = CurrentChar; quoteChar = NullChar; break; // we are done. } } // If we are inside of MarkupExtensionBracketCharacters for a particular property or position parameter, // scoop up everything inside one by one, and keep track of nested Bracket Characters in the stack. else if (_context.CurrentBracketModeParseParameters != null && _context.CurrentBracketModeParseParameters.IsBracketEscapeMode) { Stack <char> bracketCharacterStack = _context.CurrentBracketModeParseParameters.BracketCharacterStack; if (_currentSpecialBracketCharacters.StartsEscapeSequence(ch)) { bracketCharacterStack.Push(ch); } else if (_currentSpecialBracketCharacters.EndsEscapeSequence(ch)) { if (_currentSpecialBracketCharacters.Match(bracketCharacterStack.Peek(), ch)) { bracketCharacterStack.Pop(); } else { throw new XamlParseException(this, SR.Get(SRID.InvalidClosingBracketCharacers, ch.ToString())); } } else if (ch == Backslash) { escaped = true; } if (bracketCharacterStack.Count == 0) { _context.CurrentBracketModeParseParameters.IsBracketEscapeMode = false; } if (!escaped) { sb.Append(ch); } } else { bool done = false; switch (ch) { case Space: if (_state == StringState.Type) { done = true; // we are done. break; } sb.Append(ch); break; case OpenCurlie: braceCount++; sb.Append(ch); break; case CloseCurlie: if (braceCount == 0) { done = true; } else { braceCount--; sb.Append(ch); } break; case Comma: done = true; // we are done. break; case EqualSign: _state = StringState.Property; done = true; // we are done. break; case Backslash: escaped = true; break; case Quote1: case Quote2: if (!atStart) { throw new XamlParseException(this, SR.Get(SRID.QuoteCharactersOutOfPlace)); } quoteChar = ch; wasQuoted = true; break; default: // All other character (including whitespace) if (_currentSpecialBracketCharacters != null && _currentSpecialBracketCharacters.StartsEscapeSequence(ch)) { Stack <char> bracketCharacterStack = _context.CurrentBracketModeParseParameters.BracketCharacterStack; bracketCharacterStack.Clear(); bracketCharacterStack.Push(ch); _context.CurrentBracketModeParseParameters.IsBracketEscapeMode = true; } sb.Append(ch); break; } if (done) { if (braceCount > 0) { throw new XamlParseException(this, SR.Get(SRID.UnexpectedTokenAfterME)); } else { if (_context.CurrentBracketModeParseParameters?.BracketCharacterStack.Count > 0) { throw new XamlParseException(this, SR.Get(SRID.MalformedBracketCharacters, ch.ToString())); } } PushBack(); break; // we are done. } } atStart = false; Advance(); } if (quoteChar != NullChar) { throw new XamlParseException(this, SR.Get(SRID.UnclosedQuote)); } string result = sb.ToString(); if (!wasQuoted) { result = result.TrimEnd(KnownStrings.WhitespaceChars); result = result.TrimStart(KnownStrings.WhitespaceChars); } if (_state == StringState.Property) { _currentParameterName = result; _currentSpecialBracketCharacters = GetBracketCharacterForProperty(_currentParameterName); } return(result); }
public void Read() { bool isQuotedMarkupExtension = false; bool readString = false; _tokenText = string.Empty; _tokenXamlType = null; _tokenProperty = null; _tokenNamespace = null; Advance(); AdvanceOverWhitespace(); if (IsAtEndOfInput) { _token = MeTokenType.None; return; } switch (CurrentChar) { case OpenCurlie: if (NextChar == CloseCurlie) // the {} escapes the ME. return the string. { _token = MeTokenType.String; _state = StringState.Value; readString = true; // ReadString() will strip the leading {} } else { _token = MeTokenType.Open; _state = StringState.Type; // types follow '{' } break; case Quote1: case Quote2: if (NextChar == OpenCurlie) { Advance(); // read ahead one character if (NextChar != CloseCurlie) // check for the '}' of a {} { isQuotedMarkupExtension = true; } PushBack(); // put back the read-ahead. } readString = true; // read substring" break; case CloseCurlie: _token = MeTokenType.Close; _state = StringState.Value; break; case EqualSign: _token = MeTokenType.EqualSign; _state = StringState.Value; _context.CurrentBracketModeParseParameters.IsConstructorParsingMode = false; break; case Comma: _token = MeTokenType.Comma; _state = StringState.Value; if (_context.CurrentBracketModeParseParameters.IsConstructorParsingMode) { _context.CurrentBracketModeParseParameters.IsConstructorParsingMode = ++_context.CurrentBracketModeParseParameters.CurrentConstructorParam < _context.CurrentBracketModeParseParameters.MaxConstructorParams; } break; default: readString = true; break; } if (readString) { if (_context.CurrentType.IsMarkupExtension && _context.CurrentBracketModeParseParameters != null && _context.CurrentBracketModeParseParameters.IsConstructorParsingMode) { int currentCtrParam = _context.CurrentBracketModeParseParameters.CurrentConstructorParam; _currentParameterName = _context.CurrentLongestConstructorOfMarkupExtension[currentCtrParam].Name; _currentSpecialBracketCharacters = GetBracketCharacterForProperty(_currentParameterName); } string str = ReadString(); _token = (isQuotedMarkupExtension) ? MeTokenType.QuotedMarkupExtension : MeTokenType.String; switch (_state) { case StringState.Value: break; case StringState.Type: _token = MeTokenType.TypeName; ResolveTypeName(str); break; case StringState.Property: _token = MeTokenType.PropertyName; ResolvePropertyName(str); break; } _state = StringState.Value; _tokenText = RemoveEscapes(str); } }