예제 #1
0
        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());
        }
예제 #2
0
        /// <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()));
        }
예제 #3
0
        // 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);
        }