private object[] PopulateJPlusArray(List <IJsonPlusNode> jv, out ErrorRecord error) { if (jv == null) { throw new ArgumentNullException(nameof(jv)); } error = null; // do not recurse over the max if (_maxRecurseLevel > -1) { _recurseLevel += 1; if (_recurseLevel > _maxRecurseLevel) { return(null); } } List <object> results = new List <object>(); for (int i = 0; i < jv.Count; i++) { IJsonPlusNode current = jv[i]; if (current.Type == JsonPlusType.Empty) { results.Add(null); } else if (current.Type == JsonPlusType.Literal) { results.Add(PopulateJPlusLeaf(current.GetValue(), out error)); } else if (current.Type == JsonPlusType.Object) { results.Add(PopulateJPlusObject(current.GetObject(), out error)); _recurseLevel -= 1; } else if (current.Type == JsonPlusType.Array) { results.Add(PopulateJPlusArray(current.GetArray(), out error)); _recurseLevel -= 1; } else { error = new ErrorRecord(new JsonPlusException(string.Format(RS.JsonPlusAmbiguousTypeInArray, i)), "UnsupportedJsonPlusDataType", ErrorCategory.ParserError, null); } // terminate immediately if there's an error if (error != null) { return(null); } } return(results.ToArray()); }
/// <see cref="JsonPlusValue.Equals(IJsonPlusNode)"/> public bool Equals(IJsonPlusNode other) { if (other is null) { return(false); } if (ReferenceEquals(this, other)) { return(true); } if (other.Type != JsonPlusType.Object) { return(false); } return(this.AsEnumerable().SequenceEqual(other.GetObject().AsEnumerable())); }
// The owner in this context can be either an object or an array. private JsonPlusObject ParseObject(IJsonPlusNode owner) { JsonPlusObject jpObject = new JsonPlusObject(owner); if (_tokens.Current.Type != TokenType.StartOfObject && _tokens.Current.Type != TokenType.LiteralValue && _tokens.Current.Type != TokenType.Include) { throw JsonPlusParserException.Create(_tokens.Current, Path, string.Format(RS.UnexpectedTokenWith2AltInObject, TokenType.StartOfObject, TokenType.LiteralValue, _tokens.Current.Type)); } bool headless = true; if (_tokens.Current.Type == TokenType.StartOfObject) { headless = false; ConsumeWhitelines(); } IJsonPlusNode lastValue = null; bool parsing = true; while (parsing) { switch (_tokens.Current.Type) { case TokenType.Include: case TokenType.OptionalInclude: if (lastValue != null) { throw JsonPlusParserException.Create(_tokens.Current, Path, string.Format(RS.UnexpectedTokenWith2AltInObject, TokenType.ArraySeparator, TokenType.EndOfLine, _tokens.Current.Type)); } lastValue = ParseInclude(jpObject); break; case TokenType.LiteralValue: if (_tokens.Current.IsNonSignificant()) { ConsumeWhitespace(); } if (_tokens.Current.Type != TokenType.LiteralValue) { break; } if (lastValue != null) { throw JsonPlusParserException.Create(_tokens.Current, Path, string.Format(RS.UnexpectedTokenWith2AltInObject, TokenType.ArraySeparator, TokenType.EndOfLine, _tokens.Current.Type)); } lastValue = ParseObjectMember(jpObject); break; // TODO: can an object be declared floating without being assigned to a field? //case TokenType.StartOfObject: case TokenType.Comment: case TokenType.EndOfLine: switch (lastValue) { case null: ConsumeWhitelines(); break; case JsonPlusObjectMember _: break; default: ((JsonPlusValue)jpObject.Parent).Add(lastValue.GetObject()); break; } lastValue = null; ConsumeWhitelines(); break; case TokenType.ArraySeparator: switch (lastValue) { case null: throw JsonPlusParserException.Create(_tokens.Current, Path, string.Format(RS.UnexpectedTokenWith2AltInObject, TokenType.Assignment, TokenType.StartOfObject, _tokens.Current.Type)); case JsonPlusObjectMember _: break; default: ((JsonPlusValue)jpObject.Parent).Add(lastValue.GetObject()); break; } lastValue = null; ConsumeWhitelines(); break; case TokenType.EndOfObject: case TokenType.EndOfFile: if (headless && _tokens.Current.Type != TokenType.EndOfFile) { throw JsonPlusParserException.Create(_tokens.Current, Path, string.Format(RS.UnexpectedTokenInObject, TokenType.EndOfFile, _tokens.Current.Type)); } if (!headless && _tokens.Current.Type != TokenType.EndOfObject) { throw JsonPlusParserException.Create(_tokens.Current, Path, string.Format(RS.UnexpectedTokenInObject, TokenType.EndOfFile, _tokens.Current.Type)); } switch (lastValue) { case null: break; case JsonPlusObjectMember _: break; default: ((JsonPlusValue)jpObject.Parent).Add(lastValue.GetObject()); break; } lastValue = null; parsing = false; break; default: throw JsonPlusParserException.Create(_tokens.Current, Path, string.Format(RS.ErrAtUnexpectedTokenInObject, _tokens.Current.Type)); } } if (_tokens.Current.Type == TokenType.EndOfObject) { _tokens.Next(); } return(jpObject); }