public JsonNode(JsonNodeKind kind, string location, String name = null)
        {
            this.kind = kind;
            this.name = name == null?kind.ToString() : name;

            this.location = location;
        }
        /// <summary>
        /// Validates that the reader is positioned on the specified node kind.
        /// </summary>
        /// <param name="jsonReader">The <see cref="JsonReader"/> to read from.</param>
        /// <param name="expectedNodeType">The expected node type.</param>
        private static void ValidateNodeKind(this IJsonReader jsonReader, JsonNodeKind expectedNodeType)
        {
            Debug.Assert(jsonReader != null, "jsonReader != null");
            Debug.Assert(expectedNodeType != JsonNodeKind.None, "expectedNodeType != JsonNodeType.None");

            if (jsonReader.NodeKind != expectedNodeType)
            {
                throw new Exception(/*Strings.JsonReader_UnexpectedJsonNodeKind(jsonReader.NodeKind, expectedNodeType)*/);
            }
        }
 public IEnumerable <JsonNode> FindAllDescendents(JsonNodeKind kind)
 {
     if (this.kind == kind)
     {
         yield return(this);
     }
     foreach (var child in children)
     {
         foreach (var match in child.FindAllDescendents(kind))
         {
             yield return(match);
         }
     }
 }
Beispiel #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="JsonReader"/> class.
        /// </summary>
        /// <param name="reader">The text reader to read input characters from.</param>
        /// <param name="options">The reader options.</param>
        public JsonReader(TextReader reader, JsonReaderOptions options)
        {
            Debug.Assert(reader != null, "reader != null");

            this.nodeKind             = JsonNodeKind.None;
            this.nodeValue            = null;
            this.reader               = reader;
            this.options              = options;
            this.storedCharacterCount = 0;
            this.tokenStartIndex      = 0;
            this.endOfInputReached    = false;
            this.allowAnnotations     = true;
            this.scopes               = new Stack <Scope>();
            this.scopes.Push(new Scope(ScopeType.Root));
        }
Beispiel #5
0
        /// <summary>
        /// Called when end of input is reached.
        /// </summary>
        /// <returns>Always returns false, used for easy readability of the callers.</returns>
        private bool EndOfInput()
        {
            // We should be ending the input only with Root in the scope.
            if (this.scopes.Count > 1)
            {
                // Not all open scopes were closed.
                throw new Exception(/*Strings.JsonReader_EndOfInputWithOpenScope*/);
            }

            Debug.Assert(
                this.scopes.Count > 0 && this.scopes.Peek().ScopeType == ScopeType.Root && this.scopes.Peek().ObjectCount <= 1,
                "The end of input should only occur with root at the top of the stack with zero or one value.");
            Debug.Assert(this.nodeValue == null, "The node value should have been reset to null.");

            this.nodeKind = JsonNodeKind.EndOfInput;

            return(false);
        }
 public static JsonNode Create(JsonNodeKind kind, string location, String name = null)
 {
     return(new JsonNode(kind, location, name));
 }
Beispiel #7
0
        public bool Read()
        {
            // Reset the node value.
            this.nodeValue = null;

#if DEBUG
            // Reset the node type to None - so that we can verify that the Read method actually sets it.
            this.nodeKind = JsonNodeKind.None;
#endif

            // Skip any whitespace characters.
            // This also makes sure that we have at least one non-whitespace character available.
            if (!this.SkipWhitespaces())
            {
                return(this.EndOfInput());
            }

            Debug.Assert(
                this.tokenStartIndex < this.storedCharacterCount && !IsWhitespaceCharacter(this.characterBuffer[this.tokenStartIndex]),
                "The SkipWhitespaces didn't correctly skip all whitespace characters from the input.");

            Scope currentScope = this.scopes.Peek();

            bool commaFound = false;
            if (this.characterBuffer[this.tokenStartIndex] == ',')
            {
                commaFound = true;
                this.tokenStartIndex++;

                // Note that validity of the comma is verified below depending on the current scope.
                // Skip all whitespaces after comma.
                // Note that this causes "Unexpected EOF" error if the comma is the last thing in the input.
                // It might not be the best error message in certain cases, but it's still correct (a JSON payload can never end in comma).
                if (!this.SkipWhitespaces())
                {
                    return(this.EndOfInput());
                }

                Debug.Assert(
                    this.tokenStartIndex < this.storedCharacterCount && !IsWhitespaceCharacter(this.characterBuffer[this.tokenStartIndex]),
                    "The SkipWhitespaces didn't correctly skip all whitespace characters from the input.");
            }

            switch (currentScope.ScopeType)
            {
            case ScopeType.Root:
                if (commaFound)
                {
                    throw new Exception(/*Strings.JsonReader_UnexpectedComma(ScopeType.Root)*/);
                }

                if (currentScope.ObjectCount > 0)
                {
                    // We already found the top-level value, so fail
                    throw new Exception(/*Strings.JsonReader_MultipleTopLevelValues*/);
                }

                // We expect a "value" - start array, start object or primitive value
                this.nodeKind = this.ParseValue();
                break;

            case ScopeType.Array:
                if (commaFound && currentScope.ObjectCount == 0)
                {
                    throw new Exception(/*Strings.JsonReader_UnexpectedComma(ScopeType.Array)*/);
                }

                // We might see end of array here
                if (this.characterBuffer[this.tokenStartIndex] == ']')
                {
                    this.tokenStartIndex++;

                    // End of array is only valid when there was no comma before it.
                    if (commaFound)
                    {
                        throw new Exception(/*Strings.JsonReader_UnexpectedComma(ScopeType.Array)*/);
                    }

                    this.PopScope();
                    this.nodeKind = JsonNodeKind.EndArray;
                    break;
                }

                if (!commaFound && currentScope.ObjectCount > 0)
                {
                    throw new Exception(/*Strings.JsonReader_MissingComma(ScopeType.Array)*/);
                }

                // We expect element which is a "value" - start array, start object or primitive value
                this.nodeKind = this.ParseValue();
                break;

            case ScopeType.Object:
                if (commaFound && currentScope.ObjectCount == 0)
                {
                    throw new Exception(/*Strings.JsonReader_UnexpectedComma(ScopeType.Object)*/);
                }

                // We might see end of object here
                if (this.characterBuffer[this.tokenStartIndex] == '}')
                {
                    this.tokenStartIndex++;

                    // End of object is only valid when there was no comma before it.
                    if (commaFound)
                    {
                        throw new Exception(/*Strings.JsonReader_UnexpectedComma(ScopeType.Object)*/);
                    }

                    this.PopScope();
                    this.nodeKind = JsonNodeKind.EndObject;
                    break;
                }
                else
                {
                    if (!commaFound && currentScope.ObjectCount > 0)
                    {
                        throw new Exception(/*Strings.JsonReader_MissingComma(ScopeType.Object)*/);
                    }

                    // We expect a property here
                    this.nodeKind = this.ParseProperty();
                    break;
                }

            case ScopeType.Property:
                if (commaFound)
                {
                    throw new Exception(/*Strings.JsonReader_UnexpectedComma(ScopeType.Property)*/);
                }

                // We expect the property value, which is a "value" - start array, start object or primitive value
                this.nodeKind = this.ParseValue();
                break;

            default:
                Debug.Assert(false, "Should never be here");
                break;
            }

            Debug.Assert(
                this.nodeKind != JsonNodeKind.None && this.nodeKind != JsonNodeKind.EndOfInput,
                "Read should never go back to None and EndOfInput should be reported by directly returning.");

            return(true);
        }
 public static bool ShouldAddStatementParent(JsonNodeKind kind)
 {
     return(AddStatementParentKinds.Contains(kind));
 }
 public static bool ShouldAddBody(JsonNodeKind kind)
 {
     return(AddBodyKinds.Contains(kind));
 }