Esempio n. 1
0
        /// <summary>
        /// Moves the reader to the bookmarked position.
        /// </summary>
        /// <param name="bookmark">The bookmark object to move to.</param>
        internal void MoveToBookmark(object bookmark)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(this.isBuffering, "Bookmarks can only be used when in buffering mode.");
            Debug.Assert(bookmark != null, "bookmark != null");

            BufferedNode bookmarkNode = bookmark as BufferedNode;

            Debug.Assert(bookmarkNode != null, "Invalid bookmark.");

#if DEBUG
            BufferedNode node          = this.bufferedNodesHead;
            bool         foundBookmark = false;
            do
            {
                if (node == bookmarkNode)
                {
                    foundBookmark = true;
                    break;
                }

                node = node.Next;
            }while (node != this.bufferedNodesHead);

            Debug.Assert(foundBookmark, "Tried to move to a bookmark which is already out of scope, bookmarks are only valid inside a single buffering session.");
#endif

            this.currentBufferedNode = bookmarkNode;
        }
Esempio n. 2
0
            /// <summary>
            /// Constructor.
            /// </summary>
            /// <param name="propertyNode">The property node to create the record for.</param>
            internal PropertyDeduplicationRecord(BufferedNode propertyNode)
            {
                Debug.Assert(propertyNode != null, "propertyNode != null");
                Debug.Assert(propertyNode.NodeType == JsonNodeType.Property, "Only property node can be stored as the property node of the deduplication record.");

                this.propertyNode = propertyNode;
            }
Esempio n. 3
0
 internal BufferingJsonReader(TextReader reader, bool removeDuplicateProperties, int maxInnerErrorDepth) : base(reader)
 {
     this.removeDuplicateProperties = removeDuplicateProperties;
     this.maxInnerErrorDepth        = maxInnerErrorDepth;
     this.bufferedNodesHead         = null;
     this.currentBufferedNode       = null;
 }
Esempio n. 4
0
        /// <summary>
        /// Puts the reader into the state where it buffers read nodes.
        /// </summary>
        internal void StartBuffering()
        {
            Debug.Assert(!this.isBuffering, "Buffering is already turned on. Must not call StartBuffering again.");

            if (this.bufferedNodesHead == null)
            {
                // capture the current state of the reader as the first item in the buffer (if there are none)
                this.bufferedNodesHead = new BufferedNode(base.NodeType, base.Value);
            }
            else
            {
                this.removeOnNextRead = false;
            }

            Debug.Assert(this.bufferedNodesHead != null, "Expected at least the current node in the buffer when starting buffering.");

            // Set the currentBufferedNode to the first node in the list; this means every time we start buffering we reset the
            // position of the current buffered node since in general we don't know how far ahead we have read before and thus don't
            // want to blindly continuing to read. The model is that with every call to StartBuffering you reset the position of the
            // current node in the list and start reading through the buffer again.
            if (this.currentBufferedNode == null)
            {
                this.currentBufferedNode = this.bufferedNodesHead;
            }

            this.isBuffering = true;
        }
Esempio n. 5
0
        private string GetAttributeWithAtomizedName(string name, string namespaceURI)
        {
            if (this.bufferedNodes.Count > 0)
            {
                for (LinkedListNode <BufferedNode> node = this.GetCurrentElementNode().AttributeNodes.First; node != null; node = node.Next)
                {
                    BufferedNode node2 = node.Value;
                    if (object.ReferenceEquals(namespaceURI, node2.NamespaceUri) && object.ReferenceEquals(name, node2.LocalName))
                    {
                        return(node.Value.Value);
                    }
                }
                return(null);
            }
            string str = null;

            while (this.reader.MoveToNextAttribute())
            {
                if (object.ReferenceEquals(name, this.reader.LocalName) && object.ReferenceEquals(namespaceURI, this.reader.NamespaceURI))
                {
                    str = this.reader.Value;
                    break;
                }
            }
            this.reader.MoveToElement();
            return(str);
        }
            /// <summary>
            /// Reorders the buffered properties to conform to the required payload order.
            /// </summary>
            /// <remarks>
            /// The required order is: odata.context comes first, odata.removed comes next (for deleted resources),
            /// then comes odata.type, then all odata.* property annotations
            /// and finally, we preserve the relative order of custom annotations and data properties.</remarks>
            internal void Reorder()
            {
                BufferedNode currentNode = this.ObjectStart;

                // Sort the property names preserving the relative order of the properties except for the OData instance annotations.
                IEnumerable <string> sortedPropertyNames = this.SortPropertyNames();

                foreach (string propertyName in sortedPropertyNames)
                {
                    Debug.Assert(this.propertyCache.ContainsKey(propertyName), "Property must be in the cache for its name to be in the list of property names.");
                    object           storedValue    = this.propertyCache[propertyName];
                    BufferedProperty storedProperty = storedValue as BufferedProperty;
                    if (storedProperty != null)
                    {
                        storedProperty.InsertAfter(currentNode);
                        currentNode = storedProperty.EndOfPropertyValueNode;
                    }
                    else
                    {
                        IEnumerable <BufferedProperty> sortedProperties = SortBufferedProperties((IList <BufferedProperty>)storedValue);
                        foreach (BufferedProperty sortedProperty in sortedProperties)
                        {
                            sortedProperty.InsertAfter(currentNode);
                            currentNode = sortedProperty.EndOfPropertyValueNode;
                        }
                    }
                }
            }
Esempio n. 7
0
        /// <summary>
        /// Reads the next node from the JSON reader and if a start-object node is detected starts reading ahead and
        /// tries to parse an in-stream error.
        /// </summary>
        /// <returns>true if a new node was found, or false if end of input was reached.</returns>
        private bool ReadNextAndCheckForInStreamError()
        {
            Debug.Assert(!this.parsingInStreamError, "!this.parsingInStreamError");

            this.parsingInStreamError = true;

            try
            {
                // read the next node in the current reader mode (buffering or non-buffering)
                bool result = this.ReadInternal();

                if (base.NodeType == JsonNodeType.StartObject)
                {
                    // If we find a StartObject node we have to read ahead and check whether this
                    // JSON object represents an in-stream error. If we are currently in buffering
                    // mode remember the current position in the buffer; otherwise start buffering.
                    bool         wasBuffering   = this.isBuffering;
                    BufferedNode storedPosition = null;
                    if (this.isBuffering)
                    {
                        storedPosition = this.currentBufferedNode;
                    }
                    else
                    {
                        this.StartBuffering();
                    }

                    // If the duplicate properties should be removed, do it here.
                    if (this.removeDuplicateProperties)
                    {
                        // The method will look for in-stream errors and throw on them as it performs the deduplication.
                        this.RemoveDuplicateProperties();
                    }
                    else
                    {
                        // read ahead and check for in-stream error
                        this.TryReadErrorAndThrow();
                    }

                    // Reset the reader state to non-buffering or to the previously
                    // backed up position in the buffer.
                    if (wasBuffering)
                    {
                        this.currentBufferedNode = storedPosition;
                    }
                    else
                    {
                        this.StopBuffering();
                    }
                }

                return(result);
            }
            finally
            {
                this.parsingInStreamError = false;
            }
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="reader">The text reader to read input characters from.</param>
        /// <param name="inStreamErrorPropertyName">The name of the property that denotes an in-stream error.</param>
        /// <param name="maxInnerErrorDepth">The maximum number of recursive internalexception objects to allow when reading in-stream errors.</param>
        /// <param name="jsonFormat">The specific JSON-based format expected by the reader.</param>
        /// <param name="isIeee754Compatible">If it is IEEE754 Compatible</param>
        internal BufferingJsonReader(TextReader reader, string inStreamErrorPropertyName, int maxInnerErrorDepth, ODataFormat jsonFormat, bool isIeee754Compatible)
            : base(reader, jsonFormat, isIeee754Compatible)
        {
            Debug.Assert(reader != null, "reader != null");

            this.inStreamErrorPropertyName = inStreamErrorPropertyName;
            this.maxInnerErrorDepth = maxInnerErrorDepth;
            this.bufferedNodesHead = null;
            this.currentBufferedNode = null;
        }
Esempio n. 9
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="reader">The text reader to read input characters from.</param>
        /// <param name="inStreamErrorPropertyName">The name of the property that denotes an in-stream error.</param>
        /// <param name="maxInnerErrorDepth">The maximum number of recursive internalexception objects to allow when reading in-stream errors.</param>
        /// <param name="jsonFormat">The specific JSON-based format expected by the reader.</param>
        /// <param name="isIeee754Compatible">If it is IEEE754 Compatible</param>
        internal BufferingJsonReader(TextReader reader, string inStreamErrorPropertyName, int maxInnerErrorDepth, ODataFormat jsonFormat, bool isIeee754Compatible)
            : base(reader, jsonFormat, isIeee754Compatible)
        {
            Debug.Assert(reader != null, "reader != null");

            this.inStreamErrorPropertyName = inStreamErrorPropertyName;
            this.maxInnerErrorDepth        = maxInnerErrorDepth;
            this.bufferedNodesHead         = null;
            this.currentBufferedNode       = null;
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="innerReader">The inner JSON reader.</param>
        /// <param name="inStreamErrorPropertyName">The name of the property that denotes an in-stream error.</param>
        /// <param name="maxInnerErrorDepth">The maximum number of recursive internalexception objects to allow when reading in-stream errors.</param>
        internal BufferingJsonReader(IJsonReader innerReader, string inStreamErrorPropertyName, int maxInnerErrorDepth)
        {
            Debug.Assert(innerReader != null, "innerReader != null");

            this.innerReader = innerReader;
            this.inStreamErrorPropertyName = inStreamErrorPropertyName;
            this.maxInnerErrorDepth        = maxInnerErrorDepth;
            this.bufferedNodesHead         = null;
            this.currentBufferedNode       = null;
        }
Esempio n. 11
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="reader">The text reader to read input characters from.</param>
        /// <param name="inStreamErrorPropertyName">The name of the property that denotes an in-stream error.</param>
        /// <param name="maxInnerErrorDepth">The maximum number of recursive internalexception objects to allow when reading in-stream errors.</param>
        /// <param name="jsonFormat">The specific JSON-based format expected by the reader.</param>
        internal BufferingJsonReader(TextReader reader, string inStreamErrorPropertyName, int maxInnerErrorDepth, ODataFormat jsonFormat)
            : base(reader, jsonFormat)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(reader != null, "reader != null");

            this.inStreamErrorPropertyName = inStreamErrorPropertyName;
            this.maxInnerErrorDepth        = maxInnerErrorDepth;
            this.bufferedNodesHead         = null;
            this.currentBufferedNode       = null;
        }
Esempio n. 12
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="reader">The text reader to read input characters from.</param>
        /// <param name="removeDuplicateProperties">true if the reader should remove duplicate properties and simulate the WCF DS Server behavior.</param>
        /// <param name="maxInnerErrorDepth">The maximumum number of recursive internalexception objects to allow when reading in-stream errors.</param>
        internal BufferingJsonReader(TextReader reader, bool removeDuplicateProperties, int maxInnerErrorDepth)
            : base(reader)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(reader != null, "reader != null");

            this.removeDuplicateProperties = removeDuplicateProperties;
            this.maxInnerErrorDepth        = maxInnerErrorDepth;
            this.bufferedNodesHead         = null;
            this.currentBufferedNode       = null;
        }
Esempio n. 13
0
        /// <summary>
        /// Moves the reader to the bookmarked position.
        /// </summary>
        /// <param name="bookmark">The bookmark object to move to.</param>
        internal void MoveToBookmark(object bookmark)
        {
            Debug.Assert(this.isBuffering, "Bookmarks can only be used when in buffering mode.");
            Debug.Assert(bookmark != null, "bookmark != null");

            BufferedNode bookmarkNode = bookmark as BufferedNode;

            Debug.Assert(bookmarkNode != null, "Invalid bookmark.");
#if DEBUG
            Debug.Assert(this.NodeExistsInCurrentBuffer(bookmarkNode), "Tried to move to a bookmark which is already out of scope, bookmarks are only valid inside a single buffering session.");
#endif

            this.currentBufferedNode = bookmarkNode;
        }
Esempio n. 14
0
 /// <summary>
 /// Removes the head node from the buffer.
 /// </summary>
 private void RemoveFirstNodeInBuffer()
 {
     if (this.bufferedNodesHead.Next == this.bufferedNodesHead)
     {
         Debug.Assert(this.bufferedNodesHead.Previous == this.bufferedNodesHead, "The linked list is corrupted.");
         this.bufferedNodesHead = null;
     }
     else
     {
         this.bufferedNodesHead.Previous.Next = this.bufferedNodesHead.Next;
         this.bufferedNodesHead.Next.Previous = this.bufferedNodesHead.Previous;
         this.bufferedNodesHead = this.bufferedNodesHead.Next;
     }
 }
Esempio n. 15
0
        /// <summary>
        /// Reads the next node from the JSON reader and if a start-object node is detected starts reading ahead and
        /// tries to parse an in-stream error.
        /// </summary>
        /// <returns>true if a new node was found, or false if end of input was reached.</returns>
        private bool ReadNextAndCheckForInStreamError()
        {
            Debug.Assert(!this.parsingInStreamError, "!this.parsingInStreamError");

            this.parsingInStreamError = true;

            try
            {
                // read the next node in the current reader mode (buffering or non-buffering)
                bool result = this.ReadInternal();

                if (base.NodeType == JsonNodeType.StartObject)
                {
                    // If we find a StartObject node we have to read ahead and check whether this
                    // JSON object represents an in-stream error. If we are currently in buffering
                    // mode remember the current position in the buffer; otherwise start buffering.
                    bool         wasBuffering   = this.isBuffering;
                    BufferedNode storedPosition = null;
                    if (this.isBuffering)
                    {
                        storedPosition = this.currentBufferedNode;
                    }
                    else
                    {
                        this.StartBuffering();
                    }

                    this.ProcessObjectValue();

                    // Reset the reader state to non-buffering or to the previously
                    // backed up position in the buffer.
                    if (wasBuffering)
                    {
                        this.currentBufferedNode = storedPosition;
                    }
                    else
                    {
                        this.StopBuffering();
                    }
                }

                return(result);
            }
            finally
            {
                this.parsingInStreamError = false;
            }
        }
Esempio n. 16
0
        private bool ReadInternal()
        {
            bool flag;

            if (this.removeOnNextRead)
            {
                if (this.bufferedNodesHead.Next == this.bufferedNodesHead)
                {
                    this.bufferedNodesHead = null;
                }
                else
                {
                    this.bufferedNodesHead.Previous.Next = this.bufferedNodesHead.Next;
                    this.bufferedNodesHead.Next.Previous = this.bufferedNodesHead.Previous;
                    this.bufferedNodesHead = this.bufferedNodesHead.Next;
                }
                this.removeOnNextRead = false;
            }
            if (this.isBuffering)
            {
                if (this.currentBufferedNode.Next != this.bufferedNodesHead)
                {
                    this.currentBufferedNode = this.currentBufferedNode.Next;
                    return(true);
                }
                if (this.parsingInStreamError)
                {
                    flag = base.Read();
                    BufferedNode node = new BufferedNode(base.NodeType, base.Value)
                    {
                        Previous = this.bufferedNodesHead.Previous,
                        Next     = this.bufferedNodesHead
                    };
                    this.bufferedNodesHead.Previous.Next = node;
                    this.bufferedNodesHead.Previous      = node;
                    this.currentBufferedNode             = node;
                    return(flag);
                }
                return(this.ReadNextAndCheckForInStreamError());
            }
            if (this.bufferedNodesHead == null)
            {
                return(this.parsingInStreamError ? base.Read() : this.ReadNextAndCheckForInStreamError());
            }
            flag = this.bufferedNodesHead.NodeType != JsonNodeType.EndOfInput;
            this.removeOnNextRead = true;
            return(flag);
        }
Esempio n. 17
0
 internal void StartBuffering()
 {
     if (this.bufferedNodesHead == null)
     {
         this.bufferedNodesHead = new BufferedNode(base.NodeType, base.Value);
     }
     else
     {
         this.removeOnNextRead = false;
     }
     if (this.currentBufferedNode == null)
     {
         this.currentBufferedNode = this.bufferedNodesHead;
     }
     this.isBuffering = true;
 }
Esempio n. 18
0
        /// <summary>
        /// Determines whether the given node exists in the current buffer.
        /// </summary>
        /// <param name="nodeToCheck">The node to test.</param>
        /// <returns>true if the given node was found in the buffer; false otherwise.</returns>
        private bool NodeExistsInCurrentBuffer(BufferedNode nodeToCheck)
        {
            BufferedNode currentNode = this.bufferedNodesHead;

            do
            {
                if (currentNode == nodeToCheck)
                {
                    return(true);
                }

                currentNode = currentNode.Next;
            }while (currentNode != this.bufferedNodesHead);

            return(false);
        }
Esempio n. 19
0
        /// <summary>
        /// Puts the reader into the state where no buffering happen on read.
        /// Either buffered nodes are consumed or new nodes are read (and not buffered).
        /// </summary>
        internal void StopBuffering()
        {
            Debug.Assert(this.isBuffering, "Buffering is not turned on. Must not call StopBuffering in this state.");

            // NOTE: by turning off buffering the reader is set to the first node in the buffer (if any) and will continue
            //       to read from there. removeOnNextRead is set to true since we captured the original state of the reader
            //       (before starting to buffer) as the first node in the buffer and that node has to be removed on the next read.
            this.isBuffering      = false;
            this.removeOnNextRead = true;

            // We set the currentBufferedNode to null here to indicate that we want to reset the position of the current
            // buffered node when we turn on buffering the next time. So far this (i.e., resetting the position of the buffered
            // node) is the only mode the BufferingJsonReader supports. We can make resetting the current node position more explicit
            // if needed.
            this.currentBufferedNode = null;
        }
Esempio n. 20
0
        public override bool MoveToFirstAttribute()
        {
            if (this.bufferedNodes.Count <= 0)
            {
                return(this.reader.MoveToFirstAttribute());
            }
            BufferedNode currentElementNode = this.GetCurrentElementNode();

            if ((currentElementNode.NodeType == XmlNodeType.Element) && (currentElementNode.AttributeNodes.Count > 0))
            {
                this.currentAttributeNode        = null;
                this.currentBufferedNodeToReport = currentElementNode.AttributeNodes.First;
                return(true);
            }
            return(false);
        }
Esempio n. 21
0
        private LinkedListNode <BufferedNode> FindAttributeBufferedNode(string localName, string namespaceUri)
        {
            BufferedNode currentElementNode = this.GetCurrentElementNode();

            if ((currentElementNode.NodeType == XmlNodeType.Element) && (currentElementNode.AttributeNodes.Count > 0))
            {
                for (LinkedListNode <BufferedNode> node2 = currentElementNode.AttributeNodes.First; node2 != null; node2 = node2.Next)
                {
                    BufferedNode node3 = node2.Value;
                    if ((string.CompareOrdinal(node3.NamespaceUri, namespaceUri) == 0) && (string.CompareOrdinal(node3.LocalName, localName) == 0))
                    {
                        return(node2);
                    }
                }
            }
            return(null);
        }
Esempio n. 22
0
 private BufferedNode BufferCurrentReaderNode()
 {
     if (this.reader.EOF)
     {
         return this.endOfInputBufferedNode;
     }
     BufferedNode node = new BufferedNode(this.reader);
     if (this.reader.NodeType == XmlNodeType.Element)
     {
         while (this.reader.MoveToNextAttribute())
         {
             node.AttributeNodes.AddLast(new BufferedNode(this.reader));
         }
         this.reader.MoveToElement();
     }
     return node;
 }
Esempio n. 23
0
        private bool ReadNextAndCheckForInStreamError()
        {
            bool flag3;

            this.parsingInStreamError = true;
            try
            {
                bool flag = this.ReadInternal();
                if (base.NodeType == JsonNodeType.StartObject)
                {
                    bool         isBuffering         = this.isBuffering;
                    BufferedNode currentBufferedNode = null;
                    if (this.isBuffering)
                    {
                        currentBufferedNode = this.currentBufferedNode;
                    }
                    else
                    {
                        this.StartBuffering();
                    }
                    if (this.removeDuplicateProperties)
                    {
                        this.RemoveDuplicateProperties();
                    }
                    else
                    {
                        this.TryReadErrorAndThrow();
                    }
                    if (isBuffering)
                    {
                        this.currentBufferedNode = currentBufferedNode;
                    }
                    else
                    {
                        this.StopBuffering();
                    }
                }
                flag3 = flag;
            }
            finally
            {
                this.parsingInStreamError = false;
            }
            return(flag3);
        }
Esempio n. 24
0
        private BufferedNode BufferCurrentReaderNode()
        {
            if (this.reader.EOF)
            {
                return(this.endOfInputBufferedNode);
            }
            BufferedNode node = new BufferedNode(this.reader);

            if (this.reader.NodeType == XmlNodeType.Element)
            {
                while (this.reader.MoveToNextAttribute())
                {
                    node.AttributeNodes.AddLast(new BufferedNode(this.reader));
                }
                this.reader.MoveToElement();
            }
            return(node);
        }
Esempio n. 25
0
        private LinkedListNode <BufferedNode> FindAttributeBufferedNode(int index)
        {
            BufferedNode currentElementNode = this.GetCurrentElementNode();

            if ((currentElementNode.NodeType == XmlNodeType.Element) && (currentElementNode.AttributeNodes.Count > 0))
            {
                LinkedListNode <BufferedNode> first = currentElementNode.AttributeNodes.First;
                int num = 0;
                while (first != null)
                {
                    if (num == index)
                    {
                        return(first);
                    }
                    num++;
                    first = first.Next;
                }
            }
            return(null);
        }
Esempio n. 26
0
        public override bool ReadAttributeValue()
        {
            if (this.bufferedNodes.Count <= 0)
            {
                return(this.reader.ReadAttributeValue());
            }
            if (this.currentBufferedNodeToReport.Value.NodeType != XmlNodeType.Attribute)
            {
                return(false);
            }
            if (this.currentAttributeNode != null)
            {
                return(false);
            }
            BufferedNode node = new BufferedNode(this.currentBufferedNodeToReport.Value.Value, this.currentBufferedNodeToReport.Value.Depth, this.NameTable);
            LinkedListNode <BufferedNode> node2 = new LinkedListNode <BufferedNode>(node);

            this.currentAttributeNode        = this.currentBufferedNodeToReport;
            this.currentBufferedNodeToReport = node2;
            return(true);
        }
Esempio n. 27
0
        private bool ReadInternal(bool ignoreInStreamErrors)
        {
            bool flag;

            if (this.removeOnNextRead)
            {
                this.currentBufferedNodeToReport = this.currentBufferedNodeToReport.Next;
                this.bufferedNodes.RemoveFirst();
                this.removeOnNextRead = false;
            }
            if (this.isBuffering)
            {
                this.MoveFromAttributeValueNode();
                if (this.currentBufferedNode.Next != null)
                {
                    this.currentBufferedNode         = this.currentBufferedNode.Next;
                    this.currentBufferedNodeToReport = this.currentBufferedNode;
                    return(true);
                }
                if (ignoreInStreamErrors)
                {
                    flag = this.reader.Read();
                    this.bufferedNodes.AddLast(this.BufferCurrentReaderNode());
                    this.currentBufferedNode         = this.bufferedNodes.Last;
                    this.currentBufferedNodeToReport = this.currentBufferedNode;
                    return(flag);
                }
                return(this.ReadNextAndCheckForInStreamError());
            }
            if (this.bufferedNodes.Count == 0)
            {
                return(ignoreInStreamErrors ? this.reader.Read() : this.ReadNextAndCheckForInStreamError());
            }
            this.currentBufferedNodeToReport = this.bufferedNodes.First;
            BufferedNode node = this.currentBufferedNodeToReport.Value;

            flag = !this.IsEndOfInputNode(node);
            this.removeOnNextRead = true;
            return(flag);
        }
Esempio n. 28
0
 internal BufferingXmlReader(XmlReader reader, Uri parentXmlBaseUri, Uri documentBaseUri, bool disableXmlBase, int maxInnerErrorDepth, string odataNamespace)
 {
     this.reader = reader;
     this.documentBaseUri = documentBaseUri;
     this.disableXmlBase = disableXmlBase;
     this.maxInnerErrorDepth = maxInnerErrorDepth;
     XmlNameTable nameTable = this.reader.NameTable;
     this.XmlNamespace = nameTable.Add("http://www.w3.org/XML/1998/namespace");
     this.XmlBaseAttributeName = nameTable.Add("base");
     this.XmlLangAttributeName = nameTable.Add("lang");
     this.ODataMetadataNamespace = nameTable.Add("http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
     this.ODataNamespace = nameTable.Add(odataNamespace);
     this.ODataErrorElementName = nameTable.Add("error");
     this.bufferedNodes = new LinkedList<BufferedNode>();
     this.currentBufferedNode = null;
     this.endOfInputBufferedNode = BufferedNode.CreateEndOfInput(this.reader.NameTable);
     this.xmlBaseStack = new Stack<XmlBaseDefinition>();
     if (parentXmlBaseUri != null)
     {
         this.xmlBaseStack.Push(new XmlBaseDefinition(parentXmlBaseUri, 0));
     }
 }
Esempio n. 29
0
        private LinkedListNode <BufferedNode> FindAttributeBufferedNode(string qualifiedName)
        {
            BufferedNode currentElementNode = this.GetCurrentElementNode();

            if ((currentElementNode.NodeType == XmlNodeType.Element) && (currentElementNode.AttributeNodes.Count > 0))
            {
                for (LinkedListNode <BufferedNode> node2 = currentElementNode.AttributeNodes.First; node2 != null; node2 = node2.Next)
                {
                    BufferedNode node3 = node2.Value;
                    bool         flag  = !string.IsNullOrEmpty(node3.Prefix);
                    if (!flag && (string.CompareOrdinal(node3.LocalName, qualifiedName) == 0))
                    {
                        return(node2);
                    }
                    if (flag && (string.CompareOrdinal(node3.Prefix + ":" + node3.LocalName, qualifiedName) == 0))
                    {
                        return(node2);
                    }
                }
            }
            return(null);
        }
            /// <summary>
            /// Reorders the buffered property to be positioned after the <paramref name="node"/> node.
            /// </summary>
            /// <param name="node">The node after which to insert this buffered property.</param>
            internal void InsertAfter(BufferedNode node)
            {
                Debug.Assert(node != null, "node != null");

                // First take out the nodes representing the property from the linked list
                BufferedNode predecessor = this.PropertyNameNode.Previous;
                Debug.Assert(predecessor != null, "There must always be a predecessor for a property node.");
                BufferedNode successor = this.EndOfPropertyValueNode.Next;
                Debug.Assert(successor != null, "There should always be at least the end-object node after the property value.");
                predecessor.Next = successor;
                successor.Previous = predecessor;

                // Then insert the nodes representing the property after the 'insertAfter' node
                successor = node.Next;
                node.Next = this.PropertyNameNode;
                this.PropertyNameNode.Previous = node;
                this.EndOfPropertyValueNode.Next = successor;
                if (successor != null)
                {
                    successor.Previous = this.EndOfPropertyValueNode;
                }
            }
Esempio n. 31
0
        internal BufferingXmlReader(XmlReader reader, Uri parentXmlBaseUri, Uri documentBaseUri, bool disableXmlBase, int maxInnerErrorDepth, string odataNamespace)
        {
            this.reader             = reader;
            this.documentBaseUri    = documentBaseUri;
            this.disableXmlBase     = disableXmlBase;
            this.maxInnerErrorDepth = maxInnerErrorDepth;
            XmlNameTable nameTable = this.reader.NameTable;

            this.XmlNamespace           = nameTable.Add("http://www.w3.org/XML/1998/namespace");
            this.XmlBaseAttributeName   = nameTable.Add("base");
            this.XmlLangAttributeName   = nameTable.Add("lang");
            this.ODataMetadataNamespace = nameTable.Add("http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
            this.ODataNamespace         = nameTable.Add(odataNamespace);
            this.ODataErrorElementName  = nameTable.Add("error");
            this.bufferedNodes          = new LinkedList <BufferedNode>();
            this.currentBufferedNode    = null;
            this.endOfInputBufferedNode = BufferedNode.CreateEndOfInput(this.reader.NameTable);
            this.xmlBaseStack           = new Stack <XmlBaseDefinition>();
            if (parentXmlBaseUri != null)
            {
                this.xmlBaseStack.Push(new XmlBaseDefinition(parentXmlBaseUri, 0));
            }
        }
Esempio n. 32
0
 /// <summary>
 /// Removes the head node from the buffer.
 /// </summary>
 private void RemoveFirstNodeInBuffer()
 {
     if (this.bufferedNodesHead.Next == this.bufferedNodesHead)
     {
         Debug.Assert(this.bufferedNodesHead.Previous == this.bufferedNodesHead, "The linked list is corrupted.");
         this.bufferedNodesHead = null;
     }
     else
     {
         this.bufferedNodesHead.Previous.Next = this.bufferedNodesHead.Next;
         this.bufferedNodesHead.Next.Previous = this.bufferedNodesHead.Previous;
         this.bufferedNodesHead = this.bufferedNodesHead.Next;
     }
 }
Esempio n. 33
0
        /// <summary>
        /// Puts the reader into the state where it buffers read nodes.
        /// </summary>
        internal void StartBuffering()
        {
            Debug.Assert(!this.isBuffering, "Buffering is already turned on. Must not call StartBuffering again.");

            if (this.bufferedNodesHead == null)
            {
                // capture the current state of the reader as the first item in the buffer (if there are none)
                this.bufferedNodesHead = new BufferedNode(base.NodeType, base.Value);
            }
            else
            {
                this.removeOnNextRead = false;
            }

            Debug.Assert(this.bufferedNodesHead != null, "Expected at least the current node in the buffer when starting buffering.");

            // Set the currentBufferedNode to the first node in the list; this means every time we start buffering we reset the 
            // position of the current buffered node since in general we don't know how far ahead we have read before and thus don't 
            // want to blindly continuing to read. The model is that with every call to StartBuffering you reset the position of the
            // current node in the list and start reading through the buffer again.
            if (this.currentBufferedNode == null)
            {
                this.currentBufferedNode = this.bufferedNodesHead;
            }

            this.isBuffering = true;
        }
Esempio n. 34
0
        /// <summary>
        /// Reads the next node from the input. If we have still nodes in the buffer, takes the node
        /// from there. Otherwise reads a new node from the underlying reader and buffers it (depending on the current mode).
        /// </summary>
        /// <returns>true if a new node was found, or false if end of input was reached.</returns>
        /// <remarks>
        /// If the parsingInStreamError field is false, the method will read ahead for every StartObject node read from the input to check whether the JSON object
        /// represents an in-stream error. If so, it throws an <see cref="ODataErrorException"/>. If false, this check will not happen.
        /// This parsingInStremError field is set to true when trying to parse an in-stream error; in normal operation it is false.
        /// </remarks>
        protected bool ReadInternal()
        {
            if (this.removeOnNextRead)
            {
                Debug.Assert(this.bufferedNodesHead != null, "If removeOnNextRead is true we must have at least one node in the buffer.");

                this.RemoveFirstNodeInBuffer();

                this.removeOnNextRead = false;
            }

            bool result;

            if (this.isBuffering)
            {
                Debug.Assert(this.currentBufferedNode != null, "this.currentBufferedNode != null");

                if (this.currentBufferedNode.Next != this.bufferedNodesHead)
                {
                    this.currentBufferedNode = this.currentBufferedNode.Next;
                    result = true;
                }
                else
                {
                    if (this.parsingInStreamError)
                    {
                        // read more from the input stream and buffer it
                        result = base.Read();

                        // Add the new node to the end
                        BufferedNode newNode = new BufferedNode(base.NodeType, base.Value);
                        newNode.Previous = this.bufferedNodesHead.Previous;
                        newNode.Next     = this.bufferedNodesHead;
                        this.bufferedNodesHead.Previous.Next = newNode;
                        this.bufferedNodesHead.Previous      = newNode;
                        this.currentBufferedNode             = newNode;
                    }
                    else
                    {
                        // read the next node from the input stream and check
                        // whether it is an in-stream error
                        result = this.ReadNextAndCheckForInStreamError();
                    }
                }
            }
            else
            {
                if (this.bufferedNodesHead == null)
                {
                    // if parsingInStreamError nothing in the buffer; read from the base,
                    // else read the next node from the input stream and check
                    // whether it is an in-stream error
                    result = this.parsingInStreamError ? base.Read() : this.ReadNextAndCheckForInStreamError();
                }
                else
                {
                    Debug.Assert(!this.parsingInStreamError, "!this.parsingInStreamError");

                    // non-buffering read from the buffer
                    result = this.bufferedNodesHead.NodeType != JsonNodeType.EndOfInput;
                    this.removeOnNextRead = true;
                }
            }

            return(result);
        }
Esempio n. 35
0
        /// <summary>
        /// Moves the reader to the bookmarked position.
        /// </summary>
        /// <param name="bookmark">The bookmark object to move to.</param>
        internal void MoveToBookmark(object bookmark)
        {
            Debug.Assert(this.isBuffering, "Bookmarks can only be used when in buffering mode.");
            Debug.Assert(bookmark != null, "bookmark != null");

            BufferedNode bookmarkNode = bookmark as BufferedNode;
            Debug.Assert(bookmarkNode != null, "Invalid bookmark.");
#if DEBUG
            Debug.Assert(this.NodeExistsInCurrentBuffer(bookmarkNode), "Tried to move to a bookmark which is already out of scope, bookmarks are only valid inside a single buffering session.");
#endif

            this.currentBufferedNode = bookmarkNode;
        }
Esempio n. 36
0
        /// <summary>
        /// Puts the reader into the state where no buffering happen on read.
        /// Either buffered nodes are consumed or new nodes are read (and not buffered).
        /// </summary>
        internal void StopBuffering()
        {
            Debug.Assert(this.isBuffering, "Buffering is not turned on. Must not call StopBuffering in this state.");

            // NOTE: by turning off buffering the reader is set to the first node in the buffer (if any) and will continue
            //       to read from there. removeOnNextRead is set to true since we captured the original state of the reader
            //       (before starting to buffer) as the first node in the buffer and that node has to be removed on the next read.
            this.isBuffering = false;
            this.removeOnNextRead = true;

            // We set the currentBufferedNode to null here to indicate that we want to reset the position of the current 
            // buffered node when we turn on buffering the next time. So far this (i.e., resetting the position of the buffered
            // node) is the only mode the BufferingJsonReader supports. We can make resetting the current node position more explicit
            // if needed.
            this.currentBufferedNode = null;
        }
Esempio n. 37
0
 public override bool ReadAttributeValue()
 {
     if (this.bufferedNodes.Count <= 0)
     {
         return this.reader.ReadAttributeValue();
     }
     if (this.currentBufferedNodeToReport.Value.NodeType != XmlNodeType.Attribute)
     {
         return false;
     }
     if (this.currentAttributeNode != null)
     {
         return false;
     }
     BufferedNode node = new BufferedNode(this.currentBufferedNodeToReport.Value.Value, this.currentBufferedNodeToReport.Value.Depth, this.NameTable);
     LinkedListNode<BufferedNode> node2 = new LinkedListNode<BufferedNode>(node);
     this.currentAttributeNode = this.currentBufferedNodeToReport;
     this.currentBufferedNodeToReport = node2;
     return true;
 }
Esempio n. 38
0
        /// <summary>Constructor</summary>
        /// <param name="reader">The reader to wrap.</param>
        /// <param name="parentXmlBaseUri">If this reader is wrapping an inner reader of some kind, this parameter should pass the xml:base effective value of the parent.</param>
        /// <param name="documentBaseUri">The base URI for the document.</param>
        /// <param name="disableXmlBase">Flag to control if the xml:base attributes should be processed when reading.</param>
        /// <param name="maxInnerErrorDepth">The maximum number of recursive internalexception elements to allow when reading in-stream errors.</param>
        /// <param name="odataNamespace">XML namespace for data services.</param>
        internal BufferingXmlReader(XmlReader reader, Uri parentXmlBaseUri, Uri documentBaseUri, bool disableXmlBase, int maxInnerErrorDepth, string odataNamespace)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(reader != null, "reader != null");
            Debug.Assert(documentBaseUri == null || documentBaseUri.IsAbsoluteUri, "The document Base URI must be absolute if it's specified.");

            this.reader = reader;
            this.documentBaseUri = documentBaseUri;
            this.disableXmlBase = disableXmlBase;
            this.maxInnerErrorDepth = maxInnerErrorDepth;

            XmlNameTable nameTable = this.reader.NameTable;
            this.XmlNamespace = nameTable.Add(AtomConstants.XmlNamespace);
            this.XmlBaseAttributeName = nameTable.Add(AtomConstants.XmlBaseAttributeName);
            this.XmlLangAttributeName = nameTable.Add(AtomConstants.XmlLangAttributeName);
            this.ODataMetadataNamespace = nameTable.Add(AtomConstants.ODataMetadataNamespace);
            this.ODataNamespace = nameTable.Add(odataNamespace);
            this.ODataErrorElementName = nameTable.Add(AtomConstants.ODataErrorElementName);

            this.bufferedNodes = new LinkedList<BufferedNode>();
            this.currentBufferedNode = null;
            this.endOfInputBufferedNode = BufferedNode.CreateEndOfInput(this.reader.NameTable);
            this.xmlBaseStack = new Stack<XmlBaseDefinition>();

            // If there's a parent xml:base we need to push it onto our stack so that it's correctly propagated
            // Note that it's not the same as using it as documentBaseUri, since that one is only used to resolve relative xml:base values
            // not to report if there's no xml:base.
            if (parentXmlBaseUri != null)
            {
                this.xmlBaseStack.Push(new XmlBaseDefinition(parentXmlBaseUri, 0));
            }
        }
Esempio n. 39
0
 /// <summary>
 /// Determines if the specified node is the end of input node.
 /// </summary>
 /// <param name="node">The buffered node to test.</param>
 /// <returns>true if the node is the special end of input node, false otherwise.</returns>
 private bool IsEndOfInputNode(BufferedNode node)
 {
     return object.ReferenceEquals(node, this.endOfInputBufferedNode);
 }
Esempio n. 40
0
        /// <summary>
        /// Removes duplicate properties in the current object record.
        /// </summary>
        /// <remarks>
        /// This method assumes that we are buffering and that the current buffered node is a StartObject.
        /// It then goes, buffers the entire object record (and all its children) and removes duplicate properties (using the WCF DS Server algorithm).
        /// It will remove duplicate properties on any objects in the subtree of the top-level object as well (behaves recursively).
        /// The method also checks for in-stream errors and throws if it finds one.
        /// </remarks>
        private void RemoveDuplicateProperties()
        {
            Debug.Assert(this.removeDuplicateProperties, "The RemoveDuplicateProperties method should only be called if the removal of duplicate properties is turned on.");
            Debug.Assert(this.currentBufferedNode.NodeType == JsonNodeType.StartObject, "this.currentBufferedNode.NodeType == JsonNodeType.StartObject");
            Debug.Assert(this.parsingInStreamError, "this.parsingInStreamError");
            this.AssertBuffering();

            // Read ahead the entire object and create a map of properties.
            // This will buffer the object record we are on and all its children (the entire subtree).
            // We store a stack, which holds an item for each object record we find.
            // Each item on this stack is a dictionary
            //   - key is the name of the property of a property in the object record
            //   - value is a List<PropertyDeduplicationRecord>, in this list we store a new record
            //     every time we find a property of a given name for the objet record.
            //     This stores pointer to the property node and pointer to the node after the property value.
            Stack <ObjectRecordPropertyDeduplicationRecord> objectRecordStack = new Stack <ObjectRecordPropertyDeduplicationRecord>();

            do
            {
                if (this.currentBufferedNode.NodeType == JsonNodeType.StartObject)
                {
                    // New object record - add the node to our stack
                    objectRecordStack.Push(new ObjectRecordPropertyDeduplicationRecord());

                    // See if it's an in-stream error
                    BufferedNode startObjectPosition = this.currentBufferedNode;
                    this.TryReadErrorAndThrow();
                    this.currentBufferedNode = startObjectPosition;
                }
                else if (this.currentBufferedNode.NodeType == JsonNodeType.EndObject)
                {
                    // End of object record
                    // Pop the node from our stack
                    ObjectRecordPropertyDeduplicationRecord currentObjectRecord = objectRecordStack.Pop();

                    // If there is a current property, mark its last value node.
                    if (currentObjectRecord.CurrentPropertyRecord != null)
                    {
                        currentObjectRecord.CurrentPropertyRecord.LastPropertyValueNode = this.currentBufferedNode.Previous;
                    }

                    // Now walk the list of properties for the object record and deduplicate them
                    foreach (List <PropertyDeduplicationRecord> propertyDeduplicationRecords in currentObjectRecord.Values)
                    {
                        // If there's just one property of this name - there's nothing to do.
                        if (propertyDeduplicationRecords.Count <= 1)
                        {
                            continue;
                        }

                        // Walk all the properties and each time remove the property we find from its current place and move it
                        // inplace of the first property. Note that since the property names are the same we can replace the property node itself
                        // without losing any information.
                        // Once we walk the entire list the outcome will be that we will have just one property of a given name,
                        // it will be in the position of the first property, but it will be the last property value.
                        // We could completely remove the property occurences which are not first or last, but it's easier to move them
                        // to the first one by one as it keeps the algorithm simple (and the performence difference is small enough).
                        PropertyDeduplicationRecord firstProperty = propertyDeduplicationRecords[0];
                        for (int propertyIndex = 1; propertyIndex < propertyDeduplicationRecords.Count; propertyIndex++)
                        {
                            PropertyDeduplicationRecord currentProperty = propertyDeduplicationRecords[propertyIndex];
                            Debug.Assert((string)firstProperty.PropertyNode.Value == (string)currentProperty.PropertyNode.Value, "The property names must be the same.");

                            // Note that property nodes must be preceded at least by the start object node and followed by the end object node
                            // so we don't have to check for end of list here.
                            // Remove the current property from the list
                            currentProperty.PropertyNode.Previous.Next          = currentProperty.LastPropertyValueNode.Next;
                            currentProperty.LastPropertyValueNode.Next.Previous = currentProperty.PropertyNode.Previous;

                            // Now replace the first property with the current property
                            firstProperty.PropertyNode.Previous.Next          = currentProperty.PropertyNode;
                            currentProperty.PropertyNode.Previous             = firstProperty.PropertyNode.Previous;
                            firstProperty.LastPropertyValueNode.Next.Previous = currentProperty.LastPropertyValueNode;
                            currentProperty.LastPropertyValueNode.Next        = firstProperty.LastPropertyValueNode.Next;
                            firstProperty = currentProperty;
                        }
                    }

                    if (objectRecordStack.Count == 0)
                    {
                        break;
                    }
                }
                else if (this.currentBufferedNode.NodeType == JsonNodeType.Property)
                {
                    ObjectRecordPropertyDeduplicationRecord currentObjectRecord = objectRecordStack.Peek();

                    // If there is a previous property record, mark its last value node.
                    if (currentObjectRecord.CurrentPropertyRecord != null)
                    {
                        currentObjectRecord.CurrentPropertyRecord.LastPropertyValueNode = this.currentBufferedNode.Previous;
                    }

                    // Create a new property record for this property node and add it to the object record.
                    currentObjectRecord.CurrentPropertyRecord = new PropertyDeduplicationRecord(this.currentBufferedNode);
                    string propertyName = (string)this.currentBufferedNode.Value;
                    List <PropertyDeduplicationRecord> propertyDeduplicationRecords;
                    if (!currentObjectRecord.TryGetValue(propertyName, out propertyDeduplicationRecords))
                    {
                        propertyDeduplicationRecords = new List <PropertyDeduplicationRecord>();
                        currentObjectRecord.Add(propertyName, propertyDeduplicationRecords);
                    }

                    propertyDeduplicationRecords.Add(currentObjectRecord.CurrentPropertyRecord);
                }
            }while (this.ReadInternal());
        }
Esempio n. 41
0
        /// <summary>
        /// Reads the next node from the input. If we have still nodes in the buffer, takes the node
        /// from there. Otherwise reads a new node from the underlying reader and buffers it (depending on the current mode).
        /// </summary>
        /// <returns>true if a new node was found, or false if end of input was reached.</returns>
        /// <remarks>
        /// If the parsingInStreamError field is false, the method will read ahead for every StartObject node read from the input to check whether the JSON object 
        /// represents an in-stream error. If so, it throws an <see cref="ODataErrorException"/>. If false, this check will not happen.
        /// This parsingInStremError field is set to true when trying to parse an in-stream error; in normal operation it is false.
        /// </remarks>
        protected bool ReadInternal()
        {
            if (this.removeOnNextRead)
            {
                Debug.Assert(this.bufferedNodesHead != null, "If removeOnNextRead is true we must have at least one node in the buffer.");

                this.RemoveFirstNodeInBuffer();

                this.removeOnNextRead = false;
            }

            bool result;
            if (this.isBuffering)
            {
                Debug.Assert(this.currentBufferedNode != null, "this.currentBufferedNode != null");

                if (this.currentBufferedNode.Next != this.bufferedNodesHead)
                {
                    this.currentBufferedNode = this.currentBufferedNode.Next;
                    result = true;
                }
                else
                {
                    if (this.parsingInStreamError)
                    {
                        // read more from the input stream and buffer it
                        result = base.Read();

                        // Add the new node to the end
                        BufferedNode newNode = new BufferedNode(base.NodeType, base.Value);
                        newNode.Previous = this.bufferedNodesHead.Previous;
                        newNode.Next = this.bufferedNodesHead;
                        this.bufferedNodesHead.Previous.Next = newNode;
                        this.bufferedNodesHead.Previous = newNode;
                        this.currentBufferedNode = newNode;
                    }
                    else
                    {
                        // read the next node from the input stream and check
                        // whether it is an in-stream error
                        result = this.ReadNextAndCheckForInStreamError();
                    }
                }
            }
            else
            {
                if (this.bufferedNodesHead == null)
                {
                    // if parsingInStreamError nothing in the buffer; read from the base,
                    // else read the next node from the input stream and check
                    // whether it is an in-stream error
                    result = this.parsingInStreamError ? base.Read() : this.ReadNextAndCheckForInStreamError();
                }
                else
                {
                    Debug.Assert(!this.parsingInStreamError, "!this.parsingInStreamError");

                    // non-buffering read from the buffer
                    result = this.bufferedNodesHead.NodeType != JsonNodeType.EndOfInput;
                    this.removeOnNextRead = true;
                }
            }

            return result;
        }
Esempio n. 42
0
        /// <summary>
        /// Determines whether the given node exists in the current buffer.
        /// </summary>
        /// <param name="nodeToCheck">The node to test.</param>
        /// <returns>true if the given node was found in the buffer; false otherwise.</returns>
        private bool NodeExistsInCurrentBuffer(BufferedNode nodeToCheck)
        {
            BufferedNode currentNode = this.bufferedNodesHead;

            do
            {
                if (currentNode == nodeToCheck)
                {
                    return true;
                }

                currentNode = currentNode.Next;
            }
            while (currentNode != this.bufferedNodesHead);

            return false;
        }
Esempio n. 43
0
        /// <summary>
        /// Reads the next node from the value of an attribute.
        /// </summary>
        /// <returns>true if next node was available; false if end of the attribute value was reached.</returns>
        public override bool ReadAttributeValue()
        {
            this.ValidateInternalState();

            if (this.bufferedNodes.Count > 0)
            {
                if (this.currentBufferedNodeToReport.Value.NodeType != XmlNodeType.Attribute)
                {
                    return false;
                }

                // If we're already on an attribute value node, return false, since we always report the entire attribute value as one node.
                if (this.currentAttributeNode != null)
                {
                    return false;
                }

                // Otherwise create the new "fake" node for the attribute value
                BufferedNode attributeValueBufferedNode = new BufferedNode(this.currentBufferedNodeToReport.Value.Value, this.currentBufferedNodeToReport.Value.Depth, this.NameTable);
                LinkedListNode<BufferedNode> attributeValueNode = new LinkedListNode<BufferedNode>(attributeValueBufferedNode);
                this.currentAttributeNode = this.currentBufferedNodeToReport;
                this.currentBufferedNodeToReport = attributeValueNode;

                this.ValidateInternalState();
                return true;
            }
            
            return this.reader.ReadAttributeValue();
        }
Esempio n. 44
0
        /// <summary>
        /// Reads the next node from the JSON reader and if a start-object node is detected starts reading ahead and
        /// tries to parse an in-stream error.
        /// </summary>
        /// <returns>true if a new node was found, or false if end of input was reached.</returns>
        private bool ReadNextAndCheckForInStreamError()
        {
            Debug.Assert(!this.parsingInStreamError, "!this.parsingInStreamError");

            this.parsingInStreamError = true;

            try
            {
                // read the next node in the current reader mode (buffering or non-buffering)
                bool result = this.ReadInternal();

                if (base.NodeType == JsonNodeType.StartObject)
                {
                    // If we find a StartObject node we have to read ahead and check whether this
                    // JSON object represents an in-stream error. If we are currently in buffering
                    // mode remember the current position in the buffer; otherwise start buffering.
                    bool wasBuffering = this.isBuffering;
                    BufferedNode storedPosition = null;
                    if (this.isBuffering)
                    {
                        storedPosition = this.currentBufferedNode;
                    }
                    else
                    {
                        this.StartBuffering();
                    }

                    this.ProcessObjectValue();

                    // Reset the reader state to non-buffering or to the previously
                    // backed up position in the buffer.
                    if (wasBuffering)
                    {
                        this.currentBufferedNode = storedPosition;
                    }
                    else
                    {
                        this.StopBuffering();
                    }
                }

                return result;
            }
            finally
            {
                this.parsingInStreamError = false;
            }
        }
Esempio n. 45
0
        /// <summary>
        /// Buffers the current reader state into a node.
        /// </summary>
        /// <returns>The newly created buffered node.</returns>
        private BufferedNode BufferCurrentReaderNode()
        {
            if (this.reader.EOF)
            {
                return this.endOfInputBufferedNode;
            }

            BufferedNode resultNode = new BufferedNode(this.reader);

            // If the new node is an element, read all its attributes and buffer those as well
            if (this.reader.NodeType == XmlNodeType.Element)
            {
                while (this.reader.MoveToNextAttribute())
                {
                    resultNode.AttributeNodes.AddLast(new BufferedNode(this.reader));
                }

                this.reader.MoveToElement();
            }

            return resultNode;
        }
Esempio n. 46
0
            /// <summary>
            /// Reorders the buffered property to be positioned after the <paramref name="node"/> node.
            /// </summary>
            /// <param name="node">The node after which to insert this buffered property.</param>
            internal void InsertAfter(BufferedNode node)
            {
                Debug.Assert(node != null, "node != null");

                // First take out the nodes representing the property from the linked list
                BufferedNode predecessor = this.PropertyNameNode.Previous;
                Debug.Assert(predecessor != null, "There must always be a predecessor for a property node.");
                BufferedNode successor = this.EndOfPropertyValueNode.Next;
                Debug.Assert(successor != null, "There should always be at least the end-object node after the property value.");
                predecessor.Next = successor;
                successor.Previous = predecessor;

                // Then insert the nodes representing the property after the 'insertAfter' node
                successor = node.Next;
                node.Next = this.PropertyNameNode;
                this.PropertyNameNode.Previous = node;
                this.EndOfPropertyValueNode.Next = successor;
                if (successor != null)
                {
                    successor.Previous = this.EndOfPropertyValueNode;
                }
            }