예제 #1
0
 /// <inheritdoc/>
 internal override bool UpdateDataFrom(AXmlObject source)
 {
     if (!base.UpdateDataFrom(source)) return false;
     AXmlText src = (AXmlText)source;
     if (this.EscapedValue != src.EscapedValue ||
         this.Value != src.Value)
     {
         OnChanging();
         this.EscapedValue = src.EscapedValue;
         this.Value = src.Value;
         OnChanged();
         return true;
     } else {
         return false;
     }
 }
예제 #2
0
 /// <inheritdoc/>
 internal override bool UpdateDataFrom(AXmlObject source)
 {
     if (!base.UpdateDataFrom(source)) return false;
     AXmlElement src = (AXmlElement)source;
     // Clear the cache for this - quite expensive
     attributesAndElements = null;
     if (this.IsProperlyNested != src.IsProperlyNested ||
         this.HasStartOrEmptyTag != src.HasStartOrEmptyTag ||
         this.HasEndTag != src.HasEndTag)
     {
         OnChanging();
         this.IsProperlyNested = src.IsProperlyNested;
         this.HasStartOrEmptyTag = src.HasStartOrEmptyTag;
         this.HasEndTag = src.HasEndTag;
         OnChanged();
         return true;
     } else {
         return false;
     }
 }
예제 #3
0
        /// <summary>
        /// To be used exclusively by the children update algorithm.
        /// Insert child and keep links consistent.
        /// </summary>
        void InsertChild(int index, AXmlObject item)
        {
            AXmlParser.Log("Inserting {0} at index {1}", item, index);

            Assert(this.Document != null, "Can not insert to dangling object");
            Assert(item.Parent != this, "Can not own item twice");

            SetParentPointersInTree(item);

            this.Children.InsertItemAt(index, item);

            this.Document.OnObjectInserted(index, item);
        }
예제 #4
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
            }
        }
예제 #5
0
 /// <inheritdoc/>
 internal override bool UpdateDataFrom(AXmlObject source)
 {
     if (!base.UpdateDataFrom(source)) return false;
     AXmlAttribute src = (AXmlAttribute)source;
     if (this.Name != src.Name ||
         this.EqualsSign != src.EqualsSign ||
         this.QuotedValue != src.QuotedValue ||
         this.Value != src.Value)
     {
         OnChanging();
         this.Name = src.Name;
         this.EqualsSign = src.EqualsSign;
         this.QuotedValue = src.QuotedValue;
         this.Value = src.Value;
         OnChanged();
         return true;
     } else {
         return false;
     }
 }
예제 #6
0
 // Only these four methods should be used to modify the collection
 /// <summary> To be used exlucively by the parser </summary>
 internal void AddChild(AXmlObject item)
 {
     // Childs can be only added to newly parsed items
     Assert(this.Parent == null, "I have to be new");
     Assert(item.IsCached, "Added item must be in cache");
     // Do not set parent pointer
     this.Children.InsertItemAt(this.Children.Count, item);
 }
예제 #7
0
 /// <inheritdoc/>
 internal override bool UpdateDataFrom(AXmlObject source)
 {
     if (!base.UpdateDataFrom(source)) return false;
     AXmlTag src = (AXmlTag)source;
     if (this.OpeningBracket != src.OpeningBracket ||
         this.Name != src.Name ||
         this.ClosingBracket != src.ClosingBracket)
     {
         OnChanging();
         this.OpeningBracket = src.OpeningBracket;
         this.Name = src.Name;
         this.ClosingBracket = src.ClosingBracket;
         OnChanged();
         return true;
     } else {
         return false;
     }
 }
예제 #8
0
 internal void OnObjectRemoved(int index, AXmlObject obj)
 {
     if (ObjectRemoved != null)
         ObjectRemoved(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, new AXmlObject[] { obj }.ToList(), index));
 }
예제 #9
0
 internal void OnObjectChanging(AXmlObject obj)
 {
     if (ObjectChanging != null)
         ObjectChanging(this, new AXmlObjectEventArgs() { Object = obj } );
 }
예제 #10
0
        /// <summary> Copy all data from the 'source' to this object </summary>
        /// <remarks> Returns true if any updates were done </remarks>
        internal virtual bool UpdateDataFrom(AXmlObject source)
        {
            Assert(this.GetType() == source.GetType(), "Source has different type");
            DebugAssert(this.StartOffset == source.StartOffset, "Source has different StartOffset");

            if (this.LastUpdatedFrom == source) {
                DebugAssert(this.EndOffset == source.EndOffset, "Source has different EndOffset");
                return false;
            }

            Assert(!this.IsCached, "Can not update cached item");
            Assert(source.IsCached, "Must update from cache");

            this.LastUpdatedFrom = source;
            this.StartOffset = source.StartOffset;
            // In some cases we are just updating objects of that same
            // type and position and hoping to be luckily right
            this.EndOffset = source.EndOffset;

            // Do not bother comparing - assume changed if non-null
            if (this.syntaxErrors != null || source.syntaxErrors != null) {
                // May be called again in derived class - oh, well, does not matter
                OnChanging();
                this.Document.Parser.TrackedSegments.RemoveSyntaxErrorsOf(this);
                if (source.syntaxErrors == null) {
                    this.syntaxErrors = null;
                } else {
                    this.syntaxErrors = new List<SyntaxError>();
                    foreach(var error in source.MySyntaxErrors) {
                        // The object differs, so create our own copy
                        // The source still might need it in the future and we do not want to break it
                        this.AddSyntaxError(error.Clone(this));
                    }
                }
                this.Document.Parser.TrackedSegments.AddSyntaxErrorsOf(this);
                OnChanged();
            }

            return true;
        }
예제 #11
0
 /// <summary> Is call to UpdateDataFrom is allowed? </summary>
 internal bool CanUpdateDataFrom(AXmlObject source)
 {
     return
         this.GetType() == source.GetType() &&
         this.StartOffset == source.StartOffset &&
         (this.LastUpdatedFrom == source || !this.IsCached);
 }