private void ParseTokens() { if (_tokens.Current.IsNonSignificant()) { ConsumeWhitelines(); } while (_tokens.Current.Type != TokenType.EndOfFile) { switch (_tokens.Current.Type) { case TokenType.Include: case TokenType.OptionalInclude: _root.Add(ParseInclude(_root)); break; // may contain one array and one array only case TokenType.StartOfArray: _root.Add(ParseArray(_root)); break; case TokenType.StartOfObject: _root.Add(ParseObject(_root).GetObject()); break; case TokenType.LiteralValue: if (_tokens.Current.IsNonSignificant()) { ConsumeWhitelines(); } if (_tokens.Current.Type != TokenType.LiteralValue) { break; } _root.Add(ParseObject(_root).GetObject()); break; case TokenType.Comment: case TokenType.EndOfLine: case TokenType.EndOfFile: case TokenType.EndOfObject: case TokenType.EndOfArray: _tokens.Next(); break; default: throw JsonPlusParserException.Create(_tokens.Current, null, string.Format(RS.IllegalTokenType, _tokens.Current.Type), null); } } }
/// <see cref="IJsonPlusNode.Clone(IJsonPlusNode)"/> public virtual IJsonPlusNode Clone(IJsonPlusNode newParent) { JsonPlusValue clone = new JsonPlusValue(newParent); foreach (IJsonPlusNode value in this) { clone.Add(value.Clone(clone)); } return(clone); }
internal void EnsureMemberIsObject() { if (Type == JsonPlusType.Object) { return; } JsonPlusValue v = new JsonPlusValue(this); JsonPlusObject o = new JsonPlusObject(v); v.Add(o); _internalValues.Add(v); }
internal JsonPlusValue OlderValueThan(IJsonPlusNode marker) { List <JsonPlusObject> objectList = new List <JsonPlusObject>(); int index = 0; while (index < _internalValues.Count) { JsonPlusValue value = _internalValues[index]; if (value.Any(v => ReferenceEquals(v, marker))) { break; } switch (value.Type) { case JsonPlusType.Object: objectList.Add(value.GetObject()); break; case JsonPlusType.Literal: case JsonPlusType.Array: objectList.Clear(); break; } index++; } if (objectList.Count == 0) { return(index == 0 ? null : _internalValues[index - 1]); } JsonPlusValue result = new JsonPlusValue(null); JsonPlusObject o = new JsonPlusObject(result); result.Add(o); foreach (JsonPlusObject obj in objectList) { o.Merge(obj); } return(result); }
private void ResolveAllSubstitution(bool resolveEnv) { foreach (JsonPlusSubstitution sub in _substitutions) { // Retrieve value JsonPlusValue res; try { res = ResolveSubstitution(sub); } catch (JsonPlusException e) { throw JsonPlusParserException.Create(sub, sub.Path, string.Format(RS.SubstitutionError, e.Message), e); } if (res != null) { sub.ResolvedValue = res; continue; } if (resolveEnv) { // Try to pull value from environment string envValue = null; try { envValue = Environment.GetEnvironmentVariable(sub.Path.Value); } catch (Exception) { // ignored } if (envValue != null) { // undefined value resolved to an environment variable res = new JsonPlusValue(sub.Parent); if (envValue.NeedQuotes()) { res.Add(new QuotedStringValue(sub.Parent, envValue)); } else { res.Add(new UnquotedStringValue(sub.Parent, envValue)); } sub.ResolvedValue = res; continue; } } // ${ throws exception if it is not resolved if (sub.Required) { throw JsonPlusParserException.Create(sub, sub.Path, string.Format(RS.UnresolvedSubstitution, sub.Path)); } sub.ResolvedValue = new EmptyValue(sub.Parent); } }
/// <summary> /// Retrieves the next value token from the tokenizer and appends it /// to the supplied element <paramref name="owner"/>. /// </summary> /// <param name="owner">The element to append the next token.</param> /// <exception cref="Exception">End of file reached while trying to read a value</exception> private JsonPlusValue ParseValue(IJsonPlusNode owner) { JsonPlusValue value = new JsonPlusValue(owner); bool parsing = true; while (parsing) { switch (_tokens.Current.Type) { case TokenType.Include: case TokenType.OptionalInclude: value.Add(ParseInclude(value)); break; case TokenType.LiteralValue: // Consume leading whitespaces. if (_tokens.Current.IsNonSignificant()) { ConsumeWhitespace(); } if (_tokens.Current.Type != TokenType.LiteralValue) { break; } while (_tokens.Current.Type == TokenType.LiteralValue) { value.Add(JsonPlusLiteralValue.Create(value, _tokens.Current)); _tokens.Next(); } break; case TokenType.StartOfObject: value.Add(ParseObject(value)); break; case TokenType.StartOfArray: value.Add(ParseArray(value)); break; case TokenType.OptionalSubstitution: case TokenType.Substitution: JsonPlusPath pointerPath = JsonPlusPath.Parse(_tokens.Current.Value); JsonPlusSubstitution sub = new JsonPlusSubstitution(value, pointerPath, _tokens.Current, _tokens.Current.Type == TokenType.Substitution); _substitutions.Add(sub); value.Add(sub); _tokens.Next(); break; case TokenType.EndOfObject: case TokenType.EndOfArray: parsing = false; break; // comments automatically stop value parsing. case TokenType.Comment: ConsumeWhitelines(); parsing = false; break; case TokenType.EndOfLine: parsing = false; break; case TokenType.EndOfFile: case TokenType.ArraySeparator: parsing = false; break; case TokenType.SelfAssignment: JsonPlusSubstitution subAssign = new JsonPlusSubstitution(value, new JsonPlusPath(Path), _tokens.Current, false); _substitutions.Add(subAssign); value.Add(subAssign); value.Add(ParseSelfAssignArray(value)); parsing = false; break; case TokenType.Assignment: ConsumeWhitelines(); break; default: throw JsonPlusParserException.Create(_tokens.Current, Path, string.Format(RS.ErrAtUnexpectedToken, _tokens.Current.Type)); } } // trim trailing whitespace if result is a literal if (value.Type == JsonPlusType.Literal) { if (value[value.Count - 1] is WhitespaceValue) { value.RemoveAt(value.Count - 1); } } return(value); }