示例#1
0
        void InsertAndUpdateChildrenFrom(IList <AXmlObject> srcList)
        {
            for (int i = 0; i < srcList.Count; i++)
            {
                // End of our list?
                if (i == this.Children.Count)
                {
                    InsertChild(i, srcList[i]);
                    continue;
                }
                AXmlObject child    = this.Children[i];
                AXmlObject srcChild = srcList[i];

                if (child.CanUpdateDataFrom(srcChild))                   // includes offset test
                // Does it need updating?
                {
                    if (child.LastUpdatedFrom != srcChild)
                    {
                        child.UpdateDataFrom(srcChild);
                        AXmlContainer childAsContainer = child as AXmlContainer;
                        if (childAsContainer != null)
                        {
                            childAsContainer.InsertAndUpdateChildrenFrom(((AXmlContainer)srcChild).Children);
                        }
                    }
                }
                else
                {
                    InsertChild(i, srcChild);
                }
            }
            Assert(this.Children.Count == srcList.Count, "List lengths differ after update");
        }
示例#2
0
        void RemoveChildrenNotIn(IList <AXmlObject> srcList)
        {
            Dictionary <int, AXmlObject> srcChildren = srcList.ToDictionary(i => i.StartOffset);

            for (int i = 0; i < this.Children.Count;)
            {
                AXmlObject child = this.Children[i];
                AXmlObject srcChild;

                if (srcChildren.TryGetValue(child.StartOffset, out srcChild) && child.CanUpdateDataFrom(srcChild))
                {
                    // Keep only one item with given offset (we might have several due to deletion)
                    srcChildren.Remove(child.StartOffset);
                    // If contaner that needs updating
                    AXmlContainer childAsContainer = child as AXmlContainer;
                    if (childAsContainer != null && child.LastUpdatedFrom != srcChild)
                    {
                        childAsContainer.RemoveChildrenNotIn(((AXmlContainer)srcChild).Children);
                    }
                    i++;
                }
                else
                {
                    RemoveChild(i);
                }
            }
        }
示例#3
0
 /// <remarks>
 /// Note the the method is not called recuively.
 /// Only the helper methods are recursive.
 /// </remarks>
 internal void UpdateTreeFrom(AXmlContainer srcContainer)
 {
     this.StartOffset = srcContainer.StartOffset;             // Force the update
     this.UpdateDataFrom(srcContainer);
     RemoveChildrenNotIn(srcContainer.Children);
     InsertAndUpdateChildrenFrom(srcContainer.Children);
 }
示例#4
0
 /// <inheritdoc/>
 public override IEnumerable <AXmlObject> GetSelfAndAllChildren()
 {
     return((new AXmlObject[] { this }).Flatten(
                delegate(AXmlObject i) {
         AXmlContainer container = i as AXmlContainer;
         if (container != null)
         {
             return container.Children;
         }
         else
         {
             return null;
         }
     }
                ));
 }
示例#5
0
        /// <summary> Recursively fix all parent pointer in a tree </summary>
        /// <remarks>
        /// Cache constraint:
        ///    If cached item has parent set, then the whole subtree must be consistent and document set
        /// </remarks>
        void SetParentPointersInTree(AXmlObject item)
        {
            // All items come from the parser cache

            if (item.Parent == null)
            {
                // Dangling object - either a new parser object or removed tree (still cached)
                item.Parent   = this;
                item.Document = this.Document;
                AXmlContainer container = item as AXmlContainer;
                if (container != null)
                {
                    foreach (AXmlObject child in container.Children)
                    {
                        container.SetParentPointersInTree(child);
                    }
                }
            }
            else if (item.Parent == this)
            {
                // If node is attached and then deattached, it will have null parent pointer
                //   but valid subtree - so its children will alredy have correct parent pointer
                //   like in this case
                // item.DebugCheckConsistency(false);
                // Rest of the tree is consistent - do not recurse
            }
            else
            {
                // From cache & parent set => consitent subtree
                // item.DebugCheckConsistency(false);
                // The parent (or any futher parents) can not be part of parsed document
                //   becuase otherwise this item would be included twice => safe to change parents
                // Maintain cache constraint by setting parents to null
                foreach (AXmlObject ancest in item.GetAncestors().ToList())
                {
                    ancest.Parent = null;
                }
                item.Parent = this;
                // Rest of the tree is consistent - do not recurse
            }
        }
        /// <summary> Removes object with all of its non-cached children </summary>
        public void RemoveParsedObject(AXmlObject obj)
        {
            // Cached objects may be used in the future - do not remove them
            if (obj.IsCached)
            {
                return;
            }
            segments.Remove(obj);
            RemoveSyntaxErrorsOf(obj);
            AXmlParser.Log("Stopped tracking {0}", obj);

            AXmlContainer container = obj as AXmlContainer;

            if (container != null)
            {
                foreach (AXmlObject child in container.Children)
                {
                    RemoveParsedObject(child);
                }
            }
        }
示例#7
0
 /// <summary>
 /// Gets a child fully containg the given offset.
 /// Goes recursively down the tree.
 /// Specail case if at the end of attribute or text
 /// </summary>
 public AXmlObject GetChildAtOffset(int offset)
 {
     foreach (AXmlObject child in this.Children)
     {
         if ((child is AXmlAttribute || child is AXmlText) && offset == child.EndOffset)
         {
             return(child);
         }
         if (child.StartOffset < offset && offset < child.EndOffset)
         {
             AXmlContainer container = child as AXmlContainer;
             if (container != null)
             {
                 return(container.GetChildAtOffset(offset));
             }
             else
             {
                 return(child);
             }
         }
     }
     return(this);            // No childs at offset
 }
		/// <remarks>
		/// Note the the method is not called recuively.
		/// Only the helper methods are recursive.
		/// </remarks>
		internal void UpdateTreeFrom(AXmlContainer srcContainer)
		{
			this.StartOffset = srcContainer.StartOffset; // Force the update
			this.UpdateDataFrom(srcContainer);
			RemoveChildrenNotIn(srcContainer.Children);
			InsertAndUpdateChildrenFrom(srcContainer.Children);
		}